序列

开始想的是树套树

但是看看数据范围 最大是1e5,那么可以用分块搞一搞,就是用想的在树套树的方法弄到分块上,因为分块这东西没有线段树的那种父子关系,当查询的时候就暴力重建每一块就行了,对于abs这东西可以二分分界点然后讨论就行了

  1 #include <cmath>
  2 #include <ctime>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <iostream>
  7 #include <algorithm>
  8 using namespace std;
  9 typedef long long LL;
 10 const int maxn=200010;
 11 void ot(){cout<<"***"<<endl;}
 12 int read(){
 13     int x=0,fg=1; char c=getchar();
 14     while(c<'0' || c>'9'){if(c=='-') fg=-1; c=getchar();}
 15     while(c>='0'&&c<='9'){x = x*10 + c-'0'; c=getchar();}
 16     return x*fg;
 17 }
 18 LL num[maxn],s[maxn],sgn[maxn],dta[maxn],sum[maxn];
 19 int n,m;
 20 int blo[maxn],len;
 21 int timer;
 22 void rebuild1(int l,int r,int w){
 23     int now=blo[l];
 24     int L=(now-1)*len+1,R=now*len;
 25     for(int i=L;i<=R;i++) num[i]+=dta[now];
 26     if(sgn[now]==-1) for(int i=L;i<=R;i++) num[i]=-num[i];
 27     sgn[now]=1; dta[now]=0;
 28     for(int i=l;i<=r;i++) num[i]+=w;
 29     memcpy(s+L,num+L,sizeof(LL)*(R-L+1));
 30     sort(s+L,s+R+1);
 31     sum[L]=s[L]; for(int i=L+1;i<=R;i++) sum[i]=sum[i-1]+s[i];
 32 }
 33 void change1(int l,int r,int w){
 34     int L,R;
 35     if(blo[l]==blo[r]){
 36         rebuild1(l,r,w);
 37         return ;
 38     }
 39     // if(timer) ot(),cout<<w<<endl;;
 40     rebuild1(l,blo[l]*len,w);
 41     rebuild1((blo[r]-1)*len+1,r,w);
 42     L=blo[l]+1; R=blo[r]-1;
 43     for(int i=L;i<=R;i++){
 44         dta[i]+=sgn[i]*w;
 45     }
 46 }
 47 void rebuild2(int l,int r){
 48     int now=blo[l];
 49     int L=(now-1)*len+1,R=now*len;
 50     for(int i=L;i<=R;i++) num[i]+=dta[now];
 51     if(sgn[now]==-1) for(int i=L;i<=R;i++) num[i]=-num[i];
 52     sgn[now]=1; dta[now]=0;
 53     for(int i=l;i<=r;i++) num[i]=-num[i];
 54     memcpy(s+L,num+L,sizeof(LL)*(R-L+1));
 55     sort(s+L,s+R+1);
 56     sum[L]=s[L]; for(int i=L+1;i<=R;i++) sum[i]=sum[i-1]+s[i];
 57 }
 58 void change2(int l,int r){
 59     int L,R;
 60     if(blo[l]==blo[r]){
 61         rebuild2(l,r); 
 62         return;
 63     }
 64     rebuild2(l,blo[l]*len);
 65     rebuild2((blo[r]-1)*len+1,r);
 66     L=blo[l]+1; R=blo[r]-1;
 67     for(int i=L;i<=R;i++){
 68         sgn[i]=-sgn[i];
 69     }
 70 }
 71 void query(int l,int r){
 72     LL ans=0; int L,R;
 73     if(blo[l]==blo[r]){
 74         for(int i=l;i<=r;i++)
 75             ans+=abs(num[i]+dta[blo[l]]);
 76         printf("%lld\n",ans);
 77         return;
 78     }
 79     R=blo[l]*len;
 80     for(int i=l;i<=R;i++) ans+=abs(num[i]+dta[blo[l]]);
 81     L=(blo[r]-1)*len+1;
 82     for(int i=L;i<=r;i++) ans+=abs(num[i]+dta[blo[r]]);
 83     L=blo[l]+1,R=blo[r]-1;
 84     int le,ri; int lim1,lim2,pos1,pos2;
 85     // cout<<"LR= "<<L<<" "<<R<<"   ans== "<<ans<<endl;
 86     for(int i=L;i<=R;i++){
 87         // cout<<"i= "<<i<<endl;
 88         le=(i-1)*len+1; ri=i*len;
 89         // cout<<" le_ri= "<<le<<" "<<ri<<endl;
 90         // cout<<" ";for(int j=le;j<=ri;j++) cout<<num[j]<<" "; cout<<endl;
 91         // cout<<" ";for(int j=le;j<=ri;j++) cout<<s[j]<<" "; cout<<endl;
 92         // cout<<" ";for(int j=le;j<=ri;j++) cout<<sum[j]<<" "; cout<<endl;
 93         if(dta[i]<0) lim1=0,lim2=-dta[i];
 94         else lim1=-dta[i],lim2=0;
 95         pos1=upper_bound(s+le,s+ri+1,lim1)-s-1;
 96         pos2=upper_bound(s+le,s+ri+1,lim2)-s-1;
 97         // cout<<" lim= "<<lim1<<"  "<<lim2<<endl;
 98         // cout<<" pos= "<<pos1<<"  "<<pos2<<endl;
 99         LL now=0;
100         if(dta[i]<=0){
101             if(pos2!=ri) now+=sum[ri]-(pos2>=le? sum[pos2]:0)+dta[i]*(ri-pos2);
102             if(pos2<=ri && pos1>=le-1) now+=-dta[i]*(pos2-pos1)-((pos2>=le? sum[pos2]:0)-(pos1>=le? sum[pos1]:0));
103             if(pos1>=le) now+=-sum[pos1]-(pos1-le+1)*dta[i];
104         }
105         else{
106             if(pos2!=ri) now+=sum[ri]-(pos2>=le? sum[pos2]:0)+dta[i]*(ri-pos2);
107             if(pos2<=ri && pos1>=le-1) now+= dta[i]*(pos2-pos1)+((pos2>=le? sum[pos2]:0)-(pos1>=le? sum[pos1]:0));
108             if(pos1>=le) now+=-sum[pos1]-(pos1-le+1)*dta[i];    
109         }
110         // cout<<"now== "<<now<<" "<<ans<<endl;
111         ans+=now;
112         // exit(0);
113     }
114     printf("%lld\n",ans);
115 }
116 void check(int id){
117     for(int i=1;i<=blo[n];i++) rebuild1((i-1)*len+1,i*len,0);
118     cout<<"i= "<<id<<" ::: "; for(int j=1;j<=n;j++) cout<<num[j]<<" "; cout<<endl;
119 }
120 int main(){
121     // freopen("seq4.in","r",stdin);
122     // freopen("my2.out","w",stdout);
123     n=read(); m=read();
124     len=180;
125     for(int i=1;i<=n;i++) num[i]=read();
126     for(int i=1;i<=n;i++) blo[i]=(i-1)/len+1;
127     for(int i=1;i<=blo[n];i++) sgn[i]=1;
128     memcpy(s,num,sizeof(s));
129     int l,r;
130     for(int i=1;i<=blo[n];i++){
131         l=(i-1)*len+1; r=i*len; if(r>n) r=n;
132         sort(s+l,s+r+1);
133         sum[l]=s[l]; for(int j=l+1;j<=r;j++) sum[j]=sum[j-1]+s[j];
134     }
135     int od,x,y,z;
136     for(int i=1;i<=m;i++){
137         od=read();
138         if(od==0){
139             x=read()+1; y=read()+1; z=read();
140             change1(x,y,z);
141         }
142         else if(od==1){
143             x=read()+1; y=read()+1;
144             change2(x,y);
145         }
146         else{
147             x=read()+1; y=read()+1;
148             query(x,y);
149         }
150     }
151     // cout<<clock()<<endl;
152 }
View Code

 

posted @ 2018-01-31 11:22  Nawox  阅读(266)  评论(0编辑  收藏  举报