zoukankan      html  css  js  c++  java
  • [CF369E]Valera and Queries_离线_树状数组

    Valera and Queries

    题目链接codeforces.com/problemset/problem/369/E

    数据范围:略。


    题解

    这种题,就单独考虑一次询问即可。

    我们发现,包括了至少一个给定点的个数,等于总个数减掉一个给定点都不包括的线段数。

    一个都不包括,就表示这个线段的在两个给定点中间,这个可以把线段抽象成二维平面上的点,然后离线+树状数组查询。

    代码

    #include <bits/stdc++.h>
    
    #define N 1000010 
    
    using namespace std;
    
    char *p1, *p2, buf[100000];
    
    #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
    
    int rd() {
    	int x = 0;
    	char c = nc();
    	while (c < 48) {
    		c = nc();
    	}
    	while (c > 47) {
    		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
    	}
    	return x;
    }
    
    int cnt = 0;
    
    struct Node {
    	int x, y1, y2, id, c, opt;
    }a[N * 10];
    
    inline bool cmp(const Node &a, const Node &b) {
    	return a.x == b.x ? a.opt > b.opt : a.x < b.x;
    }
    
    int q[N];
    
    int tree[N];
    
    inline int lowbit(int x) {
    	return x & (-x);
    }
    
    void update(int x) {
    	for (int i = x; i < N; i += lowbit(i)) {
    		tree[i] ++ ;
    	}
    }
    
    int query(int x) {
    	int ans = 0;
    	for (int i = x; i; i -= lowbit(i)) {
    		ans += tree[i];
    	}
    	return ans;
    }
    
    int ans[N];
    
    int main() {
    	int n = rd(), m = rd();
    	// opt : 1 -> query, 2 -> update
    	for (int i = 1; i <= n; i ++ ) {
    		int x = rd(), y = rd();
    		a[ ++ cnt] = (Node) {x, y, 0, 0, 1, 2};
    	}
    	// cout << cnt << endl ;
    	for (int i = 1; i <= m; i ++ ) {
    		int num = rd();
    		for (int j = 1; j <= num; j ++ ) {
    			q[j] = rd();
    		}
    		q[0] = 0;
    		q[ ++ num] = N - 1;
    		// cout << num << endl ;
    		for (int j = 1; j <= num; j ++ ) {
    			if (q[j] - q[j - 1] >= 2) {
    				// printf("Fuck %d
    ", j);
    				int x = q[j - 1] + 1, y = q[j] - 1;
    				a[ ++ cnt] = (Node) {x - 1, x, y, i, -1, 1};
    				a[ ++ cnt] = (Node) {y, x, y, i, 1, 1};
    			}
    		}
    	}
    	// cout << cnt << endl ;
    	sort(a + 1, a + cnt + 1, cmp);
    	// for (int i = 1; i <= cnt; i ++ ) {
    	// 	printf("%d %d %d %d %d %d
    ", a[i].x, a[i].y1, a[i].y2, a[i].id, a[i].c, a[i].opt);
    	// }
    	for (int i = 1; i <= cnt; i ++ ) {
    		// printf("id :: %d
    ", i);
    		if (a[i].opt == 2) {
    			update(a[i].y1);
    		}
    		else {
    			// cout << query(a[i].y2) << ' ' << query(a[i].y1) << ' ' << a[i].c << endl ;
    			// cout << (query(a[i].y2) - query(a[i].y1)) * a[i].c << endl ;
    			ans[a[i].id] += (query(a[i].y2) - query(a[i].y1)) * a[i].c;
    		}
    	}
    
    	for (int i = 1; i <= m; i ++ ) {
    		printf("%d
    ", n - ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    [转] When to use what language and why
    C++常用的函数,好的博客文章整理,集锦
    生活2013
    转-什么样的公司才是好公司?好公司的六大特征
    Linux上去掉ps grep自身查询
    Centos 上搭建FTP服务
    IOS上VOIP PUSH Notification功能
    Linux下常用命令集合
    NodeJS React 开发环境搭建
    MongoDB 命令行导入导出JSON文件
  • 原文地址:https://www.cnblogs.com/ShuraK/p/11761313.html
Copyright © 2011-2022 走看看