题意:
现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i]。每一个物品移动一步的代价为他的w[i]。目前有2种操作:
1. x y 将第x的物品的重量改为y
2.l r 将编号在 [ l, r ]之间的所有物品移动到一起,求最小的花费是多少。
带权中位数,学习了->这里
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #define ll long long 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 inline int read(){ 10 #define num ch-'0' 11 char ch;bool flag=0;int res; 12 while(!isdigit(ch=getc())) 13 (ch=='-')&&(flag=true); 14 for(res=num;isdigit(ch=getc());res=res*10+num); 15 (flag)&&(res=-res); 16 #undef num 17 return res; 18 } 19 char sr[1<<21],z[20];int C=-1,Z; 20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 21 inline void print(int x){ 22 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 23 while(z[++Z]=x%10+48,x/=10); 24 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 25 } 26 const int N=2e5+5;const ll P=1e9+7; 27 int n,q;ll a[N],w[N]; 28 namespace SUM{ 29 ll c[N]; 30 inline void add(int x,ll y){ 31 for(;x<=n;x+=x&-x) c[x]+=y; 32 } 33 inline ll que(int x){ 34 ll res=0; 35 for(;x;x-=x&-x) res+=c[x]; 36 return res; 37 } 38 inline ll query(int l,int r){ 39 if(r<l) return 0; 40 return que(r)-que(l-1); 41 } 42 } 43 namespace MUL{ 44 ll c[N]; 45 inline void add(int x,ll y){ 46 y%=P; 47 for(;x<=n;x+=x&-x) 48 (c[x]+=y+P)%=P; 49 } 50 inline ll que(int x){ 51 ll res=0; 52 for(;x;x-=x&-x) (res+=c[x])%=P; 53 return res; 54 } 55 inline ll query(int l,int r){ 56 if(r<l) return 0; 57 return (que(r)-que(l-1)+P)%P; 58 } 59 } 60 inline int getpos(int ql,int qr){ 61 int l=ql,r=qr,mid,res; 62 while(l<=r){ 63 mid=(l+r)>>1; 64 if(SUM::query(ql,mid)>=SUM::query(mid+1,qr)) res=mid,r=mid-1; 65 else l=mid+1; 66 } 67 return res; 68 } 69 void solve(int l,int r){ 70 if(l==r) return (void)(print(0)); 71 int pos=getpos(l,r);ll res=0; 72 res=(-MUL::query(l,pos)+(SUM::query(l,pos) % P)*(ll)abs(a[pos] - pos)%P+P)%P; 73 res=(res+MUL::query(pos,r)-SUM::query(pos,r)%P*(a[pos]-pos)%P+P)%P; 74 print(res); 75 } 76 int main(){ 77 // freopen("testdata.in","r",stdin); 78 n=read(),q=read(); 79 for(int i=1;i<=n;++i) a[i]=read(); 80 for(int i=1;i<=n;++i){ 81 w[i]=read(),SUM::add(i,w[i]),MUL::add(i,w[i]*(a[i]-i)); 82 } 83 while(q--){ 84 int x=read(),y=read(); 85 if(x<0){ 86 x=-x,SUM::add(x,-w[x]),MUL::add(x,-w[x]*(a[x]-x)); 87 w[x]=y,SUM::add(x,y),MUL::add(x,y*(a[x]-x)); 88 }else solve(x,y); 89 } 90 Ot(); 91 return 0; 92 }