luogu P4390 [BOI2007]Mokia 摩基亚

传送门

昨天做完三维偏序并不能理解CDQ

今天做了这个题才行

(觉得没理解三维偏序是因为二维偏序没按正常方式理解)

 

CDQ分治应用于数据结构 适用于离线的题

原理是后面的询问只能被前面的修改影响

可以分治处理 分治的左区间的修改会影响右区间的询问

这样就可以优化掉一维树状数组

 

比如说这个题 二维树状数组开不下

CDQ分治秒

我们知道二维区间和可以转成前缀和

然后只有x,y,时间都比查询小的修改才会算进去

所以树状数组维护正序对就OK啦(三维偏序)

我是按x二分 因为时间周自然排好序

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<ctime>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include <bits/stdc++.h>
 8 #define D double
 9 #define ms(a,b) memset(a,b,sizeof a)
10 #define rep(i,a,n) for(int i = a;i <= n;i++)
11 #define per(i,n,a) for(int i = n;i >= a;i--)
12 #define inf 1e8
13 using namespace std;
14 typedef long long ll;
15 #define Br puts("GG")
16 ll read() {
17     ll as = 0,fu = 1;
18     char c = getchar();
19     while(c < '0' || c > '9') {
20         if(c == '-') fu = -1;
21         c = getchar();
22     }
23     while(c >= '0' && c <= '9') {
24         as = as * 10 + c - '0';
25         c = getchar();
26     }
27     return as * fu;
28 }
29 const int N = 200005;
30 //head
31 int n,maxm,T;
32 struct node {
33     int x,y,c,op,idx;
34 } a[N];
35 node tmp[N];
36 int t[N<<4],ans[N];
37 void upd(int x,int k) {
38     for(int i = x;i <= maxm;i += (i & (-i))) t[i] += k;
39 }
40 int qry(int x) {
41     int sum = 0;
42     for(int i = x;i;i -= (i & (-i))) sum += t[i];
43     return sum;
44 }
45 
46 void CDQ(int l,int r) {
47     if(l == r) return;
48     int m = l+r >> 1;
49     CDQ(l,m),CDQ(m+1,r);
50     int p1 = l,p2 = m+1;
51     rep(i,l,r) {
52         if(p1 <= m && (p2 > r || a[p1].x <= a[p2].x)) {
53             if(!a[p1].op) upd(a[p1].y,a[p1].c);
54             tmp[i] = a[p1++];
55         } else {
56             if(a[p2].op) ans[a[p2].idx] += a[p2].c * qry(a[p2].y);
57             tmp[i] = a[p2++];
58         }
59     }
60     rep(i,l,m) if(a[i].op == 0) upd(a[i].y,-a[i].c);
61     rep(i,l,r) a[i] = tmp[i];
62 }
63 
64 int main() {
65     int op;
66     n = read(),maxm = read();
67     while((op = read()) ^ 3) {
68         if(op == 1) {
69             a[++n].x = read();a[n].y = read();
70             a[n].c = read();
71             a[n].op = a[n].idx = 0;
72         } else {
73             T++;
74             int x = read(),y = read(),A = read(),b = read();
75             a[++n] = (node){A,b,1,1,T};
76             a[++n] = (node){A,y - 1,-1,1,T};
77             a[++n] = (node){x - 1,b,-1,1,T};
78             a[++n] = (node){x - 1,y - 1,1,1,T};
79         }
80     }
81     CDQ(1,n);
82     rep(i,1,T) printf("%d\n",ans[i]);
83     return 0;
84 }
posted @ 2018-12-06 20:52  白怀潇  阅读(134)  评论(0编辑  收藏  举报