BZOJ2874 训练士兵 主席树

Posted cyz666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2874 训练士兵 主席树相关的知识,希望对你有一定的参考价值。

【啊 首先 这是道权限题,然后本人显然是没有权限的  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 }
Bad Apple!!

 











以上是关于BZOJ2874 训练士兵 主席树的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2809 [ APIO2012 ] -- 主席树

bzoj 5358[Lydsy1805月赛]口算训练

BZOJ1878: [SDOI2009]HH的项链 (主席树)

BZOJ_2223_[Coci 2009]PATULJCI_主席树

bzoj2588 -- 树链剖分+主席树

BZOJ_3524_[Poi2014]Couriers_主席树