题意:
op:对平面上任意一个点操作+v;
query:询问矩形[x1,y1,x2,y2]里面所有点v的总和;
矩形大小为20000*20000,比赛的时候看到这道题目第一直觉就是二维树状数组,但范围太大会mle,二维线段树也会mle(之后树套树的二维线段树),比赛结束后各种询问;
方法1:
用map<int,int> mp[N];来减少内存的,只在用到的地方开,没有用到的地方就不开;
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<map> 6 #include<cstdlib> 7 #include<cmath> 8 #include<vector> 9 #include<cstdlib> 10 using namespace std; 11 const int N=20000+10; 12 map<int,int > mp[N]; 13 char s[100]; 14 int lowbit(int x){ 15 return x&-x; 16 } 17 void update(int x,int y,int v){ 18 for (int i=x;i<N;i+=lowbit(i)){ 19 for (int j=y;j<N;j+=lowbit(j)){ 20 mp[i][j]+=v; 21 } 22 } 23 } 24 int sum(int x,int y){ 25 int ret=0; 26 for (int i=x;i;i-=lowbit(i)){ 27 for (int j=y;j;j-=lowbit(j)){ 28 if (mp[i].find(j)!=mp[i].end()){ 29 ret+=mp[i][j]; 30 } 31 } 32 } 33 return ret; 34 } 35 int getsum(int x1,int y1,int x2,int y2){ 36 // cout<<"---- "<<sum(x2,y2)<<" "<<sum(x1-1,y2)<<" "<<sum(x2,y1-1)<<" "<<sum(x1-1,y1-1)<<endl; 37 return sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1); 38 } 39 int main(){ 40 int flag=0; 41 int f=0; 42 while (gets(s)){ 43 for (int i=0;i<N;i++) mp[i].clear(); 44 while (1){ 45 if (s[0]=='I'){ 46 flag=1; 47 }else 48 if (s[0]=='Q'){ 49 flag=2; 50 }else 51 if (s[0]=='E') break; 52 else if (s[0]>='0' && s[0]<='9'){ 53 int x1,x2,y1,y2,v; 54 if (flag==1){ 55 sscanf(s,"%d%d%d",&x1,&y1,&v); 56 // cout<<"** "<<x1<<" "<<y1<<" "<<v<<endl; 57 update(x1,y1,v); 58 }else if (flag==2){ 59 sscanf(s,"%d%d%d%d",&x1,&x2,&y1,&y2); 60 // cout<<"/// "<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl; 61 printf("%d\n",getsum(x1,y1,x2,y2)); 62 } 63 } 64 gets(s); 65 } 66 } 67 return 0; 68 }
1 3243951 2013-04-07 20:24:28 Accepted 3018 C++ 2800 15968 Rabbit
但是时间有点慢;
方法2:
用矩阵树,即二维线段树的另外一种表示方法;
每个点表示一个矩阵,每个结点有4个结点,4个结点分别表示把这个矩阵划分成四个小矩阵,即左上,左下,右上,右下;
1 /* 2 每个结点 3 struct node{ 4 int l,r,d,u; 5 int sum;//要维护的结点的信息; 6 int ch[4];//四个小矩阵的标号; 7 }T[Maxn]; 8 更新基本同一维线段树, 9 void update(int l,int r,int d,int u,int rt,int v){ 10 if (l<=T[rt].l && T[rt].r<=r && d<=T[rt].d && T[rt].u<=u){ 11 T[rt].sum+=v; 12 return; 13 } 14 }; 15 int query(int l,int r,int d,int u,int rt){ 16 if (l<=T[rt].l && T[rt].r<=r && d<=T[rt].d && T[rt].u<=u){ 17 return T[rt].sum; 18 } 19 }; 20 为了节省空间,只对用到的结点申请内存; 21 22 */ 23 #include<cstdio> 24 #include<cstdlib> 25 #include<cstring> 26 #include<algorithm> 27 #include<iostream> 28 #include<map> 29 #include<vector> 30 #include<set> 31 #include<bitset> 32 #include<string> 33 #include<cmath> 34 using namespace std; 35 const int N=20000*15; 36 struct node{ 37 int l,r,d,u,sum; 38 int ch[4]; 39 node(){} 40 node(int a,int b,int c,int e,int f):l(a),r(b),d(c),u(e),sum(f){} 41 }T[N]; 42 43 int idx; 44 int Newnode(int l,int r,int d,int u){ 45 idx++; 46 T[idx]=node(l,r,d,u,0); 47 memset(T[idx].ch,0,sizeof(T[idx].ch)); 48 return idx; 49 } 50 void update(int x,int y,int rt,int v){ 51 if (T[rt].l==T[rt].r && T[rt].u==T[rt].d){ 52 T[rt].sum+=v; 53 return; 54 } 55 int m1=(T[rt].l+T[rt].r)>>1; 56 int m2=(T[rt].u+T[rt].d)>>1; 57 if (x<=m1 && y<=m2){//左下 58 if (T[rt].ch[0]==0){ 59 T[rt].ch[0]=Newnode(T[rt].l,m1,T[rt].d,m2); 60 } 61 update(x,y,T[rt].ch[0],v); 62 } 63 if (x<=m1 && y>m2){//左上 64 if (T[rt].ch[1]==0){ 65 T[rt].ch[1]=Newnode(T[rt].l,m1,m2+1,T[rt].u); 66 } 67 update(x,y,T[rt].ch[1],v); 68 } 69 if (x>m1 && y<=m2){//右下 70 if (T[rt].ch[2]==0){ 71 T[rt].ch[2]=Newnode(m1+1,T[rt].r,T[rt].d,m2); 72 } 73 update(x,y,T[rt].ch[2],v); 74 } 75 if (x>m1 && y>m2){//右上 76 if (T[rt].ch[3]==0){ 77 T[rt].ch[3]=Newnode(m1+1,T[rt].r,m2+1,T[rt].u); 78 } 79 update(x,y,T[rt].ch[3],v); 80 } 81 T[rt].sum=0;//合并 82 for (int i=0;i<4;i++){ 83 int c=T[rt].ch[i]; 84 T[rt].sum+=T[c].sum; 85 } 86 } 87 int query(int l,int r,int d,int u,int rt){ 88 if (l<=T[rt].l && T[rt].r<=r && d<=T[rt].d && T[rt].u<=u){ 89 return T[rt].sum; 90 } 91 int m1=(T[rt].l+T[rt].r)>>1; 92 int m2=(T[rt].u+T[rt].d)>>1; 93 int ret=0; 94 if (l<=m1 && d<=m2){ 95 if (T[rt].ch[0]!=0){ 96 ret+=query(l,r,d,u,T[rt].ch[0]); 97 } 98 } 99 if (l<=m1 && m2<u){ 100 if (T[rt].ch[1]!=0){ 101 ret+=query(l,r,d,u,T[rt].ch[1]); 102 } 103 } 104 if (m1< r && d<=m2){ 105 if (T[rt].ch[2]!=0){ 106 ret+=query(l,r,d,u,T[rt].ch[2]); 107 } 108 } 109 if (m1< r && m2< u){ 110 if (T[rt].ch[3]!=0){ 111 ret+=query(l,r,d,u,T[rt].ch[3]); 112 } 113 } 114 return ret; 115 } 116 char s[100]; 117 int main(){ 118 int flag=0; 119 while (gets(s)){ 120 idx=0; 121 Newnode(1,20000,1,20000); 122 while (1){ 123 if (s[0]=='I'){ 124 flag=1; 125 }else 126 if (s[0]=='Q'){ 127 flag=2; 128 }else 129 if (s[0]=='E') break; 130 else if (s[0]>='0' && s[0]<='9'){ 131 int x1,x2,y1,y2,v; 132 if (flag==1){ 133 sscanf(s,"%d%d%d",&x1,&y1,&v); 134 // cout<<"** "<<x1<<" "<<y1<<" "<<v<<endl; 135 update(x1,y1,1,v); 136 // cout<<"++++ "<<T[1].sum<<endl; 137 }else if (flag==2){ 138 sscanf(s,"%d%d%d%d",&x1,&x2,&y1,&y2); 139 //cout<<"/// "<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl; 140 printf("%d\n",query(x1,x2,y1,y2,1)); 141 } 142 } 143 gets(s); 144 } 145 } 146 return 0; 147 }
1 3244125 2013-04-07 22:45:19 Accepted 3018 C++ 670 10732 Rabbit