BZOJ4889:[TJOI2017]不勤勞的圖書管理員
阿新 • • 發佈:2018-12-26
淺談樹狀陣列與線段樹:https://www.cnblogs.com/AKMer/p/9946944.html
題目傳送門:https://www.lydsy.com/JudgeOnline/problem.php?id=4889
樹狀陣列套線段樹搞一搞就好了。
時間複雜度:\(O(nlog^2n)\)
空間複雜度:\(O(nlog^2n)\)
程式碼如下:
#include <cstdio> #include <algorithm> using namespace std; typedef pair<int,int> pii; #define low(i) ((i)&(-(i))) #define fr first #define sc second const int maxn=5e4+5,pps=1e9+7; int n,m,ans; int pos[maxn],v[maxn]; int read() { int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0'; return x*f; } struct segment_tree { int tot; pii tree[maxn*200]; int ls[maxn*200],rs[maxn*200]; void change(int p,int l,int r,int pos,int v,int cnt) { while(1) { tree[p].fr=(tree[p].fr+v)%pps; tree[p].sc+=cnt;if(l==r)break; int mid=(l+r)>>1; if(pos<=mid) { if(!ls[p])ls[p]=++tot; r=mid,p=ls[p]; } else { if(!rs[p])rs[p]=++tot; l=mid+1,p=rs[p]; } } } }T; struct TreeArray { int cnt1,cnt2; int rt[maxn],u1[maxn],u2[maxn]; void change(int pos,int key1,int key2,int cnt) { for(int i=pos;i<=n;i+=low(i)) { if(!rt[i])rt[i]=++T.tot; T.change(rt[i],1,n,key1,key2,cnt); } } int query(int L,int R,int pos,int val,int opt) { if(R<=L)return 0; cnt1=cnt2=0;pii res;res.fr=res.sc=0; for(int i=L;i;i-=low(i))u1[++cnt1]=rt[i]; for(int i=R;i;i-=low(i))u2[++cnt2]=rt[i]; int l=1,r=n; while(l!=r) { int mid=(l+r)>>1; if(pos<=mid) { if(opt) { for(int i=1;i<=cnt1;i++) { int u=T.rs[u1[i]]; res.fr=(res.fr-T.tree[u].fr+pps)%pps; res.sc=res.sc-T.tree[u].sc; } for(int i=1;i<=cnt2;i++) { int u=T.rs[u2[i]]; res.fr=(res.fr+T.tree[u].fr)%pps; res.sc=res.sc+T.tree[u].sc; } } r=mid; for(int i=1;i<=cnt1;i++)u1[i]=T.ls[u1[i]]; for(int i=1;i<=cnt2;i++)u2[i]=T.ls[u2[i]]; } else { if(!opt) { for(int i=1;i<=cnt1;i++) { int u=T.ls[u1[i]]; res.fr=(res.fr-T.tree[u].fr)%pps; res.sc=res.sc-T.tree[u].sc; } for(int i=1;i<=cnt2;i++) { int u=T.ls[u2[i]]; res.fr=(res.fr+T.tree[u].fr)%pps; res.sc=res.sc+T.tree[u].sc; } } l=mid+1; for(int i=1;i<=cnt1;i++)u1[i]=T.rs[u1[i]]; for(int i=1;i<=cnt2;i++)u2[i]=T.rs[u2[i]]; } } return (res.fr+1ll*res.sc*val%pps)%pps; } }bit; int main() { n=read(),m=read(); for(int i=1;i<=n;i++) { pos[i]=read(),v[i]=read(); ans=(ans+bit.query(0,i-1,pos[i],v[i],1))%pps; bit.change(i,pos[i],v[i],1); } for(int i=1;i<=m;i++) { int x=read(),y=read(); if(x>y)swap(x,y); ans=(ans-bit.query(x,y-1,pos[y],v[y],1)+pps)%pps; ans=(ans-bit.query(x,y-1,pos[x],v[x],0)+pps)%pps; ans=(ans+bit.query(x,y-1,pos[y],v[y],0))%pps; ans=(ans+bit.query(x,y-1,pos[x],v[x],1))%pps; if(pos[x]>pos[y])ans=(ans-v[x]-v[y]+pps)%pps; else if(pos[x]<pos[y])ans=(ans+v[x]+v[y])%pps; bit.change(x,pos[x],-v[x],-1),bit.change(y,pos[y],-v[y],-1); bit.change(x,pos[y],v[y],1),bit.change(y,pos[x],v[x],1); swap(pos[x],pos[y]),swap(v[x],v[y]); printf("%d\n",ans); } return 0; }