不勤劳的图书管理员
排队那道题的数据加强版,那道题是动态逆序对,这道题是动态带权逆序对,实际是差不多的。直接上线段树套动态开点线段树的板子就可以了,取模方面比较严格导致我的int写法一直没过,开龙龙宝宝就可以了。空间卡得比较死,甚至我用241M过掉的这道题(空间限制是250M,请叫我空间带师)。写法上注意两个权值的关系并正常更新答案即可。据说可以用指令集水过可能也是。。。
丑陋的代码:
#include<bits/stdc++.h>
//#define feyn
#define int long long
const int N=50010;
const int M=10000010;
const int mod=1e9+7;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,n,ans;
struct node{int pl,data;}a[N];
struct aa{int num,sum;};
inline aa operator +(aa s1,aa s2){return (aa){s1.num+s2.num,s1.sum+s2.sum};}
inline void swap(int &s1,int &s2){
int s3=s1;s1=s2;s2=s3;return;
}
inline void swapn(node &s1,node &s2){
node s3=s1;s1=s2;s2=s3;return;
}
namespace x{
#define lc t[wh].left
#define rc t[wh].right
#define mid (l+r>>1)
struct node{int left,right,num,sum;}newone,t[M];
int cnt,top,st[M];
inline int kk(){return top?st[top--]:++cnt;}
inline void del(int wh){st[++top]=wh;t[wh]=newone;}
inline void insert(int &wh,int l,int r,int pl,int val){
if(!wh)wh=kk();t[wh].num++,t[wh].sum+=val;
if(l==r)return;
if(pl<=mid)insert(lc,l,mid,pl,val);
else insert(rc,mid+1,r,pl,val);
}
inline void delet(int &wh,int l,int r,int pl,int val){
t[wh].num--,t[wh].sum-=val;
if(l^r){
if(pl<=mid)delet(lc,l,mid,pl,val);
else delet(rc,mid+1,r,pl,val);
}
if(t[wh].num==0)del(wh),wh=0;return;
}
inline aa work(int wh,int l,int r,int wl,int wr){
if(!wh)return (aa){0,0};
if(wl<=l&&r<=wr)return (aa){t[wh].num,t[wh].sum};
aa an=(aa){0,0};
if(wl<=mid)an=an+work(lc,l,mid,wl,wr);
if(wr>mid)an=an+work(rc,mid+1,r,wl,wr);
return an;
}
int rt[N<<2];
inline void solve(int wh,int bef,int aft){
if(aft==0)insert(rt[wh],1,m,a[bef].pl,a[bef].data);
else{
delet(rt[wh],1,m,a[bef].pl,a[bef].data);
insert(rt[wh],1,m,a[aft].pl,a[aft].data);
}
}
#undef lc
#undef rc
#undef mid
}
namespace y{
#define lc (wh<<1)
#define rc (wh<<1|1)
#define mid (t[wh].l+t[wh].r>>1)
struct node{
int l,r;
}t[N<<2];
void build(int wh,int l,int r){
t[wh].l=l,t[wh].r=r;
if(l==r)return;
build(lc,l,mid);
build(rc,mid+1,r);
}
inline void change(int wh,int pl,int ft){
if(pl==ft)return;
x::solve(wh,pl,ft);
if(t[wh].l==t[wh].r)return;
change(pl<=mid?lc:rc,pl,ft);
}
inline aa work(int wh,int wl,int wr,int ql,int qr){
if(wl>wr||ql>qr)return (aa){0,0};
if(wl<=t[wh].l&&t[wh].r<=wr){
return x::work(x::rt[wh],1,m,ql,qr);
}
aa an=(aa){0,0};
if(wl<=mid)an=an+work(lc,wl,wr,ql,qr);
if(wr>mid)an=an+work(rc,wl,wr,ql,qr);
return an;
}
#undef lc
#undef rc
#undef mid
}
namespace z{
#define lowbit (wh&-wh)
aa t[N];
inline void change(int wh,int val){
for(;wh<=m;wh+=lowbit)t[wh]=t[wh]+(aa){1,val};
}
inline aa work(int wh){
aa an={0,0};
for(;wh;wh-=lowbit)an=an+t[wh];
return an;
}
#undef lowbit
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);read(n);int sum=0;aa an;
for(int i=1;i<=m;i++){
read(a[i].pl);read(a[i].data);
an=z::work(a[i].pl);
ans+=(sum-an.sum)+(i-1-an.num)*a[i].data;
z::change(a[i].pl,a[i].data);
sum+=a[i].data;
}
y::build(1,1,m);
for(int i=1;i<=m;i++){
y::change(1,i,0);
}
int s1,s2;
while(n--){
read(s1);read(s2);
if(s1>s2)swap(s1,s2);
an=y::work(1,s1+1,s2-1,a[s1].pl+1,m);
ans+=an.sum+an.num*a[s1].data;
an=y::work(1,s1+1,s2-1,1,a[s1].pl-1);
ans-=an.sum+an.num*a[s1].data;
an=y::work(1,s1+1,s2-1,a[s2].pl+1,m);
ans-=an.sum+an.num*a[s2].data;
an=y::work(1,s1+1,s2-1,1,a[s2].pl-1);
ans+=an.sum+an.num*a[s2].data;
y::change(1,s1,s2);
y::change(1,s2,s1);
if(a[s1].pl>a[s2].pl)ans-=a[s1].data+a[s2].data;
if(a[s2].pl>a[s1].pl)ans+=a[s1].data+a[s2].data;
swapn(a[s1],a[s2]);
printf("%lld\n",ans%mod);
}
return 0;
}
一如既往,万事胜意