洛谷CF1030F Putting Boxes Together(树状数组)

题意:

现在有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 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9764334.html