相当于动态维护带权逆序对。
交换x,y位置的数,只会对他们之间的数产生影响。分类讨论即可。我写的线段树套权值线段树,卡空间,需要写垃圾回收qaq
复杂度 O(nlog2n)
#include
#include
#include
#include
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 50010
#define mod 1000000007
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,rt[N<<2],owo=0,cnt,sum,ans=0;
struct book{
int id,v;
}a[N];
struct node{
int cnt,lc,rc,sum;
}tr[N*256];
queue<int>rec;
inline void del(int &p){
tr[p].lc=tr[p].rc=tr[p].cnt=tr[p].sum=0;rec.push(p);p=0;
}
inline int newp(){
int p=0;
if(!rec.empty()) p=rec.front(),rec.pop();
else p=++owo;return p;
}
inline void add(int &p,int l,int r,int x,int op,int val){
if(!p) p=newp();tr[p].cnt+=op;tr[p].sum+=op*val;tr[p].sum%=mod;
if(l==r) return;int mid=l+r>>1;
if(x<=mid) add(tr[p].lc,l,mid,x,op,val);
else add(tr[p].rc,mid+1,r,x,op,val);if(!tr[p].cnt) del(p);
}
inline void ask(int p,int l,int r,int x,int y){
if(!p) return;if(x<=l&&r<=y){cnt+=tr[p].cnt;(sum+=tr[p].sum)%=mod;return;}
int mid=l+r>>1;if(x<=mid) ask(tr[p].lc,l,mid,x,y);
if(y>mid) ask(tr[p].rc,mid+1,r,x,y);
}
inline void change(int p,int l,int r,int x,int y){
if(x!=y) add(rt[p],1,n,a[x].id,-1,a[x].v);
add(rt[p],1,n,a[y].id,1,a[y].v);if(l==r) return;int mid=l+r>>1;
if(x<=mid) change(p<<1,l,mid,x,y);
else change(p<<1|1,mid+1,r,x,y);
}
inline void Ask(int p,int l,int r,int x,int y,int L,int R){
if(L>R) return;
if(x<=l&&r<=y){ask(rt[p],1,n,L,R);return;}
int mid=l+r>>1;if(x<=mid) Ask(p<<1,l,mid,x,y,L,R);
if(y>mid) Ask(p<<1|1,mid+1,r,x,y,L,R);
}
int main(){
// freopen("book5.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;++i){
a[i].id=read(),a[i].v=read(),change(1,1,n,i,i);
cnt=0;sum=0;ask(rt[1],1,n,a[i].id+1,n);
(ans+=((ll)cnt*a[i].v%mod+sum)%mod)%=mod;
}while(m--){
int x=read(),y=read();if(x>y) swap(x,y);
if(x==y){printf("%d\n",ans);continue;}
int L=a[x].id,R=a[y].id,mn=min(L,R),mx=max(L,R);
cnt=0;sum=0;Ask(1,1,n,x,y,mn+1,mx-1);
ans+=(mn==L?1:-1)*(2*sum%mod+(ll)(cnt+1)*(a[x].v+a[y].v)%mod)%mod;
ans%=mod;
cnt=0;Ask(1,1,n,x,y,1,mn-1);(ans+=(ll)cnt*(a[y].v-a[x].v)%mod)%=mod;
cnt=0;Ask(1,1,n,x,y,mx+1,n);(ans+=(ll)cnt*(a[x].v-a[y].v)%mod)%=mod;
if(ans<0) ans+=mod;
change(1,1,n,x,y);change(1,1,n,y,x);swap(a[x],a[y]);printf("%d\n",ans);
}return 0;
}