序列
开始想的是树套树
但是看看数据范围 最大是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 }