BZOJ 1176: [Balkan2007]Mokia KDtree
Description
维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.
Input
第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小
接下来每行为一下三种输入之一(不包含引号):
"1 x y a"
"2 x1 y1 x2 y2"
"3"
输入1:你需要把(x,y)(第x行第y列)的格子权值增加a
输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出
输入3:表示输入结束
Output
对于每个输入2,输出一行,即输入2的答案
题解:写一个 KDtree 即可.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin), freopen(s".out","w",stdout) #define maxn 1000000 #define mid ((l+r)>>1) using namespace std; int d,root,tot, W; struct Node { int ch[2],p[2],minv[2],maxv[2],w,sumv; }t[maxn]; bool cmp(Node a,Node b) { return a.p[d]==b.p[d]?a.p[d^1]<b.p[d^1]:a.p[d]<b.p[d]; } int isin( int x, int x1, int y1, int x2, int y2) { if (x1 <= t[x].minv[0] && x2 >= t[x].maxv[0] && y1 <= t[x].minv[1] && y2 >= t[x].maxv[1]) return 1; else return 0; } int isout( int x, int x1, int y1, int x2, int y2) { if (x1 > t[x].maxv[0] || x2 < t[x].minv[0] || y1 > t[x].maxv[1] || y2 < t[x].minv[1]) return 1; else return 0; } void pushup( int x, int y) { for ( int i=0;i<2;++i) { t[x].minv[i]=min(t[x].minv[i], t[y].minv[i]); t[x].maxv[i]=max(t[x].maxv[i], t[y].maxv[i]); } t[x].sumv+=t[y].sumv; } void insert( int &x, int o) { if (!x) { x = tot; t[tot].minv[0]=t[tot].maxv[0]=t[tot].p[0]; t[tot].minv[1]=t[tot].maxv[1]=t[tot].p[1]; t[tot].sumv=t[tot].w; t[tot].ch[0]=t[tot].ch[1]=0; return ; } d=o; if (cmp(t[tot], t[x]) == 1) { insert(t[x].ch[0], o^1); pushup(x, tot); } else { insert(t[x].ch[1],o^1); pushup(x, tot); } } int query( int x, int x1, int y1, int x2, int y2) { if (isout(x, x1, y1, x2, y2) || !x) return 0; if (isin(x, x1, y1, x2, y2)) return t[x].sumv; int tmp=0; if (t[x].p[0] >= x1 && t[x].p[0] <= x2 && t[x].p[1] >= y1 && t[x].p[1] <= y2) tmp += t[x].w; if (t[x].ch[0]) tmp += query(t[x].ch[0], x1, y1, x2, y2); if (t[x].ch[1]) tmp += query(t[x].ch[1], x1, y1, x2, y2); return tmp; } int build( int l, int r, int o) { d=o; nth_element(t+l,t+mid,t+1+r,cmp); t[mid].minv[0]=t[mid].maxv[1]=t[mid].p[0]; t[mid].minv[1]=t[mid].maxv[1]=t[mid].p[1]; t[mid].sumv = t[mid].w; t[mid].ch[0]=t[mid].ch[1]=0; if (mid > l) { t[mid].ch[0] = build(l, mid - 1, o ^ 1); pushup(mid, t[mid].ch[0]); } if (r > mid) { t[mid].ch[1] = build(mid + 1, r, o ^ 1); pushup(mid, t[mid].ch[1]); } return mid; } int main() { // setIO("input"); int S,opt,i,j,x,y,k,root = 0 ,a,b,c,d,ii=0; scanf ( "%d%d" ,&W,&S); for (ii=1;;++ii) { scanf ( "%d" ,&opt); if (opt==1) { scanf ( "%d%d%d" ,&x,&y,&k); ++tot; t[tot].p[0]=x, t[tot].p[1]=y, t[tot].w = k; insert(root, 0); } if (opt==2) { scanf ( "%d%d%d%d" ,&a,&b,&c,&d); printf ( "%d\n" ,query(root, a, b, c, d)); } if (opt==3) break ; } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步