BZOJ1176---[Balkan2007]Mokia (CDQ分治 + 树状数组)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1176
CDQ第一题,warush了好久。。
CDQ分治推荐论文:
1 《从<Cash>谈一类分治算法的应用》 陈丹琦
2 《浅谈数据结构题的几个非经典解法》 许昊然
关于CDQ分治,两种要求:①操作不相互影响 ②可以离线处理
题目描述是有问题的,,初始时 全部为0,不是s
题意:二维平面内,两种操作,1 x y v ,位于(x,y)的值加上v.。。2 x1,y1,x2,y2,,(x1,y1) (x2,y2)分别矩形的左上角右下角,查询矩形内所有元素的和。
大致思路,在x这一维上进行分治,然后y这一维直接就可以用树状数组乱搞了。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxb = 2e6+10; 7 struct Node 8 { 9 int x,y,delt; 10 int flag,idx; 11 Node(){} 12 Node(int _x,int _y,int _delt,int _flag,int _idx): 13 x(_x),y(_y),delt(_delt),flag(_flag),idx(_idx){}; 14 bool operator < (const Node &rhs)const 15 { 16 return x < rhs.x || (x == rhs.x && y < rhs.y); 17 } 18 }a[400000]; 19 struct BIT 20 { 21 int c[maxb],MAX; 22 inline int lowbit(int x) 23 { 24 return x & -x; 25 } 26 void add(int x,int val) 27 { 28 while (x <= MAX) 29 { 30 c[x] += val; 31 x += lowbit(x); 32 } 33 } 34 int sum(int x) 35 { 36 int res = 0; 37 while (x > 0) 38 { 39 res += c[x]; 40 x -= lowbit(x); 41 } 42 return res; 43 } 44 }arr; 45 46 //--------------------------------------------- 47 int ans[200000]; 48 void CDQ(int l,int r) 49 { 50 if (l == r) 51 return; 52 int mid = (l + r) >> 1; 53 CDQ(l,mid); 54 CDQ(mid+1,r); 55 int j = l; 56 for (int i = mid + 1; i <= r; i++) 57 { 58 if (a[i].flag == 2) 59 { 60 for ( ; j <= mid && a[j].x <= a[i].x; j++) 61 { 62 if (a[j].flag == 1) 63 { 64 arr.add(a[j].y,a[j].delt); 65 } 66 } 67 ans[a[i].idx] += arr.sum(a[i].y) * a[i].delt; 68 } 69 } 70 for (int i = l; i < j; i++) 71 if (a[i].flag == 1) 72 arr.add (a[i].y,-a[i].delt); 73 inplace_merge (a+l,a+mid+1,a+r+1); // 合并区间 [l,mid+1) [mid+1,r+1) 74 } 75 int main(void) 76 { 77 #ifndef ONLINE_JUDGE 78 freopen("in.txt","r",stdin); 79 #endif // ONLINE_JUDGE 80 int s,w; 81 while (~scanf ("%d%d",&s,&w)) 82 { 83 int op; 84 int tot = 1,totq = 1; 85 arr.MAX = w; 86 memset(ans,0,sizeof(ans)); 87 while (scanf ("%d",&op), op != 3) 88 { 89 if (op == 1) 90 { 91 int x,y,delt; 92 scanf ("%d%d%d",&x,&y,&delt); 93 a[tot] = Node(x,y,delt,1,tot); 94 tot++; 95 } 96 if (op == 2) 97 { 98 int x1,y1,x2,y2; 99 scanf ("%d%d%d%d",&x1,&y1,&x2,&y2); 100 a[tot] = Node(x1-1, y1-1, 1, 2, totq); tot++; 101 a[tot] = Node(x2, y1-1, -1, 2, totq); tot++; 102 a[tot] = Node(x1-1, y2, -1, 2, totq); tot++; 103 a[tot] = Node(x2, y2, 1, 2, totq); tot++; 104 totq++; 105 } 106 } 107 CDQ (1,tot-1); 108 for (int i = 1; i < totq; i++) 109 printf("%d\n",ans[i]); 110 } 111 return 0; 112 }