【啊 首先 这是道权限题,然后本人显然是没有权限的 23咳3】
最近数据结构做的越来越少。。然后 就跟上次一样 ,一做就是三四种不同写法。
等价的题面:
最近GY大神在sc2的天梯中被神族虐得很惨,表示很不爽。ryz决定帮助GY大神练习散枪兵技术。GY生产了n*m个枪兵,并站成了一个大小为n*m的方阵。ryz生产了t个电兵(高阶圣堂武士),每个电兵能对一个矩形区域造成一定的AOE伤害(也就是对该矩形区域的每个枪兵都造成相等的伤害)。但是ryz的电兵实在太多了,以至于GY无法快速计算出一个矩形区域内枪兵受到的总伤害,于是他就不知道应该优先操作哪个位置的枪兵了。虽然GY大神只要1分钟就可以秒掉这道题,但是由于他正在操作枪兵,你需要写一个程序帮他解决这个问题。
输入格式:
第一行四个正整数n,m,t,q。接下来t行,每行描述一个电兵。每行包括5个正整数x1,x2,y1,y2,d,表示对所有符合x1<=x<=x2,y1<=y<=y2的每个枪兵造成了d点伤害。
为了让同学们写更为有趣的在线询问算法,我把询问加密了,第1个询问的密码为0,第i+1个询问的密码为第i个询问的答案(mod 2^32)。
接下来q行,每行描述一个询问。每行包括2个正整数x,y。x1,x2,y1,y2按照以下方法计算(c表示该询问的密码):
x1=c % n+1,x2=(c+x) % n+1,如果x1>x2则交换x1和x2
y1=c % m+1,y2=(c+y) % m +1,如果y1>y2则交换y1和y2
你需要输出所有x1<=x<=x2,y1<=y<=y2的枪兵受到的总伤害(mod 2^32)。
输出格式:
对于每一个询问,输出一行答案mod 2^32的值。样例输入:
4 5 3 2 1 3 2 2 7 2 4 2 3 5 1 4 4 5 6 1 2 0 3
样例输出:
24 12
数据范围:
对于20%的数据,m<=10对于40%的数据,n,m<=50000,t<=30000,q<=30000
对于60%的数据,n,m<=10^5
对于另外20%的数据,所有电兵的y2-y1<=3
对于100%的数据,n,m<=10^8,t<=40000,q<=150000,d<=100000
时间限制:
5-6S (这时间应该是按测试点给的吧。。)空间限制:
1G (exm?!)。
。
。
作为曾经的数据结构狂热者。。现在大概是手感褪色。。
看到题 臆想 log方 ——好、裸题。 然后码农 最后GG。
那么 上一个GG的代码: 离散 横坐标,然后就二维线段树 空间显然过不了极限数据。时间也过不了。
1 #include <bits/stdc++.h> 2 #define U unsigned 3 using namespace std; 4 U n,m,t,T,Q,op[40005][5],A[80006],B[80006],At,Bt,al,ar,bl,br,s,w,x,ans,a1,a2,b1,b2; 5 struct ala{ U l,r,p,q,e;}a[320050]; 6 struct bla{ U l,r,ss,sw,ws,ww;}b[50000000]; 7 void build(U u){ 8 if (a[u].p==a[u].q) return; 9 U i=a[u].p+a[u].q>>1; 10 a[u].l=++t; a[t].p=a[u].p; a[t].q=i; build(t); 11 a[u].r=++t; a[t].p=i+1; a[t].q=a[u].q; build(t); 12 } 13 U finda(U x){ 14 U l=1,r=At,j; 15 while (l<r){ 16 j=l+r+1>>1; 17 A[j]<=x?l=j:r=j-1; 18 } 19 return l; 20 } 21 void add(U &u,U p,U q,U l,U r){ 22 if (!u) u=++t; 23 b[u].sw+=w*(U)(r-l+1); 24 b[u].ss+=s*(U)(r-l+1); 25 if (p==l&&q==r) { 26 b[u].ws+=s; b[u].ww+=w; return; 27 } 28 U i=p+q>>1; 29 if (r<=i) add(b[u].l,p,i,l,r); else 30 if (l>i) add(b[u].r,i+1,q,l,r); else 31 {add(b[u].l,p,i,l,i); add(b[u].r,i+1,q,i+1,r);} 32 } 33 void play(U u,U l,U r){ 34 if (a[u].p==l&&a[u].q==r){ 35 s=x*(U)(A[r+1]-A[l]); w=x; 36 add(a[u].e,1,m,bl,br); 37 return; 38 } 39 s=x*(A[r+1]-A[l]); w=0; add(a[u].e,1,m,bl,br); 40 U i=a[u].p+a[u].q>>1; 41 if (r<=i) play(a[u].l,l,r); else 42 if (l>i) play(a[u].r,l,r); else 43 {play(a[u].l,l,i); play(a[u].r,i+1,r);} 44 } 45 U getw(U u,U p,U q,U l,U r){ 46 if (!u) return 0; 47 if (p==l&&q==r) return b[u].sw; 48 U x=(r-l+1)*b[u].ww; 49 U i=p+q>>1; 50 if (r<=i) return getw(b[u].l,p,i,l,r)+x; 51 if (l>i) return getw(b[u].r,i+1,q,l,r)+x; 52 return getw(b[u].l,p,i,l,i)+getw(b[u].r,i+1,q,i+1,r)+x; 53 } 54 U gets(U u,U p,U q,U l,U r){ 55 if (!u) return 0; 56 if (p==l&&q==r) return b[u].ss; 57 U x=(r-l+1)*b[u].ws; 58 U i=p+q>>1; 59 if (r<=i) return gets(b[u].l,p,i,l,r)+x; 60 if (l>i) return gets(b[u].r,i+1,q,l,r)+x; 61 return gets(b[u].l,p,i,l,i)+gets(b[u].r,i+1,q,i+1,r)+x; 62 } 63 U qiu(U u,U l,U r){ 64 if (a[u].p==l&&a[u].q==r) return gets(a[u].e,1,m,bl,br); 65 U x=getw(a[u].e,1,m,bl,br)*(A[r+1]-A[l]); 66 U i=a[u].p+a[u].q>>1; 67 if (r<=i) return x+qiu(a[u].l,l,r); 68 if (l>i) return x+qiu(a[u].r,l,r); 69 return x+qiu(a[u].l,l,i)+qiu(a[u].r,i+1,r); 70 } 71 U qiuw(U u,U l,U r){ 72 if (a[u].p==l&&a[u].q==r) return getw(a[u].e,1,m,bl,br); 73 U x=getw(a[u].e,1,m,bl,br); 74 U i=a[u].p+a[u].q>>1; 75 if (r<=i) return x+qiuw(a[u].l,l,r); 76 if (l>i) return x+qiuw(a[u].r,l,r); 77 return x+qiuw(a[u].l,l,i)+qiuw(a[u].r,i+1,r); 78 } 79 int main(){ 80 scanf("%u%u%u%u",&n,&m,&T,&Q); 81 for (U i=1;i<=T;++i){ 82 scanf("%u%u%u%u%u",&op[i][0],&op[i][1],&op[i][2],&op[i][3],&op[i][4]); 83 if (op[i][0]>op[i][1]) swap(op[i][0],op[i][1]); 84 if (op[i][2]>op[i][3]) swap(op[i][2],op[i][3]); 85 A[i]=op[i][0]; A[i+T]=op[i][1]+1; 86 } 87 A[T+T+1]=1; 88 sort(A+1,A+T+T+2); 89 for (U i=1;i<=T+T+1;++i){ 90 if (A[i]!=A[i-1]) ++At; 91 A[At]=A[i]; 92 } 93 a[1].p=1; a[1].q=At; build(t=1); t=0; 94 A[At+1]=n+1; 95 for (U i=1;i<=T;++i){ 96 al=finda(op[i][0]); ar=finda(op[i][1]); 97 bl=op[i][2]; br=op[i][3]; 98 x=op[i][4]; play(1,al,ar); 99 } 100 while (Q--){ 101 scanf("%u%u",&a2,&br); 102 a1=ans%n+1; a2=(ans+a2)%n+1; 103 bl=ans%m+1; br=(ans+br)%m+1; 104 if (a1>a2) swap(a1,a2); 105 if (bl>br) swap(bl,br); 106 al=finda(a1); ar=finda(a2); ans=0; 107 if (al==ar) 108 ans=qiuw(1,al,al)*(a2-a1+1); 109 else{ 110 if (al+1<ar) ans+=qiu(1,al+1,ar-1); 111 ans+=qiuw(1,al,al)*(A[al+1]-a1); 112 ans+=qiuw(1,ar,ar)*(a2-A[ar]+1); 113 } 114 printf("%u\n",ans); 115 } 116 return 0; 117 }
实际 只要主席树就可以一个log了。 对第一维排序离散,另一维动态开点主席树。记录到A这个坐标的 前缀信息和当前信息。
一个重要的事故。。输入的操作。数据范围有很多问题。。具体看代码
1 #include <bits/stdc++.h> 2 #define U unsigned 3 #define Ul unsigned long long 4 using namespace std; 5 struct opt{ U x,p,q; Ul w; }op[80005]; 6 struct bla{ U l,r; Ul a,qs,ds,qw,dw; }b[5000005]; 7 bool cmp(opt a,opt b){return a.x<b.x;} 8 U n,m,T,Q,t,e[80005]; Ul A,W,ans,ax,bx,ay,by; 9 void add(U &u,U l,U r,U p,U q){ 10 b[++t]=b[u]; u=t; 11 b[u].qs+=b[u].ds*(A-b[u].a); 12 b[u].qw+=b[u].dw*(A-b[u].a); 13 b[u].a=A; b[u].ds+=W*(r-l+1); 14 if (l==p&&r==q){ b[u].dw+=W; return; } 15 U i=p+q>>1; 16 if (r<=i) add(b[u].l,l,r,p,i); else 17 if (l>i) add(b[u].r,l,r,i+1,q); else 18 {add(b[u].l,l,i,p,i); add(b[u].r,i+1,r,i+1,q);} 19 } 20 Ul get(U u,U l,U r,U p,U q){ 21 if (!u) return 0; 22 if (l==p&&q==r) return b[u].qs+b[u].ds*(A-b[u].a); 23 Ul ans=(b[u].qw+b[u].dw*(A-b[u].a))*(r-l+1); 24 U i=p+q>>1; 25 if (r<=i) return get(b[u].l,l,r,p,i)+ans; 26 if (l>i) return get(b[u].r,l,r,i+1,q)+ans; 27 return get(b[u].l,l,i,p,i)+get(b[u].r,i+1,r,i+1,q)+ans; 28 } 29 Ul qiu(U x){ 30 U l=1,r=T,j; if (x<op[1].x) return 0; 31 if (x>=op[r].x) x=op[r].x; 32 while (l<r){ 33 j=l+r+1>>1; 34 op[j].x<=x?l=j:r=j-1; 35 } 36 A=x+1; return get(e[l],ay,by,1,m); 37 } 38 int main(){ 39 scanf("%u%u%u%u",&n,&m,&T,&Q); 40 for (U i=1;i<=T;++i){ 41 U a,b,c,d; Ul e; 42 scanf("%u%u%u%u%llu",&a,&b,&c,&d,&e); 43 a=min(max((U)1,a),n); b=min(max((U)1,b),n); 44 c=min(max((U)1,c),m); d=min(max((U)1,d),m); 45 if (a>b) swap(a,b); if (c>d) swap(c,d); 46 op[i]={a,c,d,e}; op[i+T]={b+1,c,d,-e}; 47 } T<<=1; 48 sort(op+1,op+1+T,cmp); 49 for (U i=1;i<=T;++i) A=op[i].x,W=op[i].w,e[i]=e[i-1],add(e[i],op[i].p,op[i].q,1,m); 50 while (Q--){ 51 scanf("%llu%llu",&bx,&by); 52 ax=ans%n+1; ay=ans%m+1; bx=(ans+bx)%n+1; by=(ans+by)%m+1; 53 if (ax>bx) swap(ax,bx); if (ay>by) swap(ay,by); 54 ans=qiu(bx)-qiu(ax-1); printf("%llu\n",ans); 55 } 56 return 0; 57 }