1176: [Balkan2007]Mokia
Time Limit: 30 Sec Memory Limit: 162 MB
Submit: 3134 Solved: 1395
[Submit][Status][Discuss]
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的答案
Sample Input
0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
HINT
保证答案不会超过int范围
Source
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 #include<algorithm> 7 #define maxq 800000 8 #define ll long long 9 using namespace std; 10 struct data {ll id,x,y,tp,f,a,p;}t[maxq],tmp[maxq]; 11 ll s,w; 12 ll ans[maxq]; 13 int cnt; 14 bool cmp1(data t1,data t2) {return t1.x==t2.x?t1.id<t2.id:t1.x<t2.x;} 15 int ask; 16 ll sum[4000000]; 17 int lowbit(int x) {return x&(-x);} 18 bool vis[maxq]; 19 void insert(int x,ll ad) {for(int i=x;i<=w;i+=lowbit(i)) sum[i]+=ad;} 20 ll query(int x) { 21 ll re=0; 22 for(int i=x;i;i-=lowbit(i)) re+=sum[i]; 23 return re; 24 } 25 void cdq(int l,int r) { 26 if(l==r) return; 27 int mid=l+r>>1; 28 int lp=l,rp=mid+1; 29 for(int i=l;i<=r;i++) { 30 if(t[i].tp==2) { 31 if(t[i].id>mid){ans[t[i].p]+=t[i].f*query(t[i].y);vis[t[i].p]=1;} 32 } 33 else {if(t[i].id<=mid) insert(t[i].y,t[i].a);} 34 } 35 for(int i=l;i<=r;i++) if(t[i].tp==1&&t[i].id<=mid) insert(t[i].y,-t[i].a); 36 for(int i=l;i<=r;i++) { 37 if(t[i].id<=mid) tmp[lp++]=t[i]; 38 else tmp[rp++]=t[i]; 39 } 40 for(int i=l;i<=r;i++) t[i]=tmp[i]; 41 cdq(l,mid);cdq(mid+1,r); 42 } 43 void add(ll x1,ll y1,ll id,ll tp,ll f) {t[cnt].p=id;t[cnt].f=f;t[cnt].tp=tp;t[cnt].x=x1;t[cnt].y=y1;t[cnt].id=cnt;} 44 int main() { 45 scanf("%lld%lld",&s,&w); 46 int tp; 47 while(scanf("%d",&tp)) { 48 ask++; 49 if(tp==3) break; 50 if(tp==1) {cnt++;scanf("%lld%lld%lld",&t[cnt].x,&t[cnt].y,&t[cnt].a);t[cnt].id=cnt;t[cnt].tp=1;} 51 else { 52 ll x1,y1,x2,y2; 53 scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2); 54 cnt++;add(x1-1,y1-1,ask,2,1);cnt++;add(x2,y2,ask,2,1); 55 cnt++;add(x1-1,y2,ask,2,-1);cnt++;add(x2,y1-1,ask,2,-1); 56 ans[ask]+=(y2-y1+1)*(x2-x1+1)*s; 57 } 58 } 59 sort(t+1,t+cnt+1,cmp1); 60 cdq(1,cnt); 61 for(int i=1;i<=ask;i++) if(vis[i]) printf("%lld\n",ans[i]); 62 }
原文地址:https://www.cnblogs.com/wls001/p/8619185.html
时间: 2024-10-13 08:03:43