昨天做完三维偏序并不能理解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 }