Codeforces Round #216 (Div. 2) E. Valera and Queries 树状数组 离线处理
题意:n个线段[Li, Ri], m次询问, 每次询问由cnt个点组成,输出包含cnt个点中任意一个点的线段的总数。
由于是无修改的,所以我们首先应该往离线上想, 不过我是没想出来。
首先反着做,先求不包含这个cnt个点的线段的总数, 那么不包含这些点的线段必然在cnt个点之间(这里需要再加两个点一个是0, 一个是MAX),
我们可以把所有线段按Ri 分类, 然后按右端点遍历,对于当前的线段可以在Li 处+1, 然后对于每一次询问中两个点(x, y)之间线段的个数,
只需要查询 左端点大于等于x的个数就好了,这里因为是按右端点从小到大遍历的,所以不用考虑用端点了。
发现, 大多数的离线处理都是先把其中的一维从小到大排序, 然后处理另一维。 这样相当于降维。
1 #include <bits/stdc++.h> 2 3 const int maxn = 1e6 + 10; 4 typedef std::pair <int, int> pii; 5 std::vector <int> seg[maxn], q[maxn]; 6 std::vector <pii> rq[maxn]; 7 namespace FenwickTree{ 8 int arr[maxn]; 9 void inc(int x, int d){ 10 while (x < maxn){ 11 arr[x] += d; 12 x += x & -x; 13 } 14 } 15 int query(int x){ 16 int res = 0; 17 while (x > 0){ 18 res += arr[x]; 19 x -= x & -x; 20 } 21 return res; 22 } 23 int query(int ua, int ub){ 24 return query(ub) - query(ua-1); 25 } 26 } 27 int ans[maxn]; 28 void init(){ 29 memset(ans, 0, sizeof (ans)); 30 for (int i = 0; i < maxn; i++){ 31 seg[i].clear(); 32 q[i].clear(); 33 rq[i].clear(); 34 } 35 } 36 int main() 37 { 38 #ifndef ONLINE_JUDGE 39 freopen("in.txt", "r", stdin); 40 #endif // ONLINE_JUDGE 41 int n, m; 42 while (~ scanf ("%d%d", &n, &m)){ 43 init(); 44 for (int i = 0; i < n; i++){ 45 int ua, ub; 46 scanf("%d%d", &ua, &ub); 47 ua++, ub++; 48 seg[ub].push_back(ua); 49 } 50 for (int i = 0; i < m; i++){ 51 int cnt, p; 52 scanf ("%d", &cnt); 53 q[i].push_back(1); 54 while (cnt--){ 55 scanf ("%d", &p); 56 p++; 57 q[i].push_back(p); 58 } 59 q[i].push_back(maxn-1); 60 for (int j = 0; j < q[i].size()-1; j++){ 61 int ua = q[i][j]+1; 62 int ub = q[i][j+1]-1; 63 rq[ub].push_back(std::make_pair(ua, i)); 64 } 65 } 66 for (int i = 1; i < maxn; i++){ 67 for (int j = 0; j < seg[i].size(); j++){ 68 int tmp = seg[i][j]; 69 FenwickTree::inc(seg[i][j], 1); 70 } 71 for (int j = 0; j < rq[i].size(); j++){ 72 int idx = rq[i][j].second; 73 int tmp = rq[i][j].first; 74 ans[idx] += FenwickTree::query(rq[i][j].first, i); 75 } 76 } 77 for (int i = 0; i < m; i++){ 78 printf("%d\n", n - ans[i]); 79 } 80 } 81 return 0; 82 }