由于蒟蒻第一次写树套树,所以模仿了大佬@p_b_p_b的题解,虽然还没有完全领会其中的精髓,但是码出来了。样例过了,但不知为何Wa掉了。请大佬帮我指明一二或者给出一组hack数据让我自己改。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int k=0;char ch=getchar();while(!isdigit(ch))ch=getchar();
while(isdigit(ch)){k=(k<<1)+(k<<3)+(ch^48);ch=getchar();}
return k;
}
void print(int x){if(x>9)print(x/10);putchar(x%10+48);}
const int mod=1e9+7,N=5e4+2;
#define Pli pair<long long,int>
#define fs first
#define sc second
int son[N<<10][2],cnt[N<<10],tot;
long long sum[N<<10];
int que[N<<5],qsz;
#define ls son[p][0],l,mid
#define rs son[p][1],mid+1,r
inline int NewNode(){
if(!qsz) return ++tot;
return que[qsz--];
}
inline void Destroy(int &p){que[++qsz]=p;p=son[p][0]=son[p][1]=0;}
void Insert(int &p,int l,int r,int pos,int x,int num){
if(!p) p=NewNode();
cnt[p]+=num,sum[p]+=x*num;
if(l!=r) {
int mid=l+r>>1;
if(mid>=pos) Insert(ls,pos,x,num);
else Insert(rs,pos,x,num);
}
if(!cnt[p]) Destroy(p);
}
Pli Query(int p,int l,int r,int L,int R){
if(!p) return Pli(0,0);
if(l>=L&&r<=R) return Pli(sum[p],cnt[p]);
// printf("%d %d %d %d %d\n",p,l,r,L,R);
int mid=l+r>>1;
Pli anx=Pli(0,0);
if(mid>=L){ Pli a=Query(ls,L,R);anx.fs=a.fs,anx.sc=a.sc;}
if(mid<R){ Pli a=Query(rs,L,R);anx.fs=(anx.fs+a.fs)%mod,anx.sc=(anx.sc+a.sc)%mod;}
return anx;
}
#undef ls
#undef rs
/*********************************************/
#define ls p<<1,l,mid
#define rs p<<1|1,mid+1,r
int root[N<<2];
void insert(int p,int l,int r,int pos,int x,int val,int num)
{
Insert(root[p],1,N,x,val,num);
if(l==r) return ;
int mid=l+r>>1;
if(mid>=pos) insert(ls,pos,x,val,num);
else insert(rs,pos,x,val,num);
}
Pli ask(int p,int l,int r,int L,int R,int x,int y)
{
if(R==0) return Pli(0,0);
if(l>=L&&r<=R) return Query(root[p],1,N,x,y);
int mid=l+r>>1;
Pli anx=Pli(0,0);
if(mid>=L){ Pli a=ask(ls,L,R,x,y);anx.fs=a.fs,anx.sc=a.sc;}
if(mid<R){ Pli a=ask(rs,L,R,x,y);anx.fs=(anx.fs+a.fs)%mod,anx.sc=(anx.sc+a.sc)%mod;}
return anx;
}
#undef ls
#undef rs
#define Pt(x) print(x),putchar('\n')
int n,m,pl[N],pg[N];
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++)
{
pl[i]=read(),pg[i]=read();
insert(1,1,n,i,pl[i],pg[i],1);
}
//check
// while(1){
// int l=read(),r=read(),x=read(),y=read();
// Pli a=ask(1,1,n,l,r,x,y);
// printf("%lld %d\n",a.fs,a.sc);
// }
// printf("Part1 is over!\n");
//
long long ans=0;
for(int i=1;i<=n;i++)
{
Pli a=ask(1,1,n,1,pl[i]-1,pg[i]+1,N);
ans=(ans+1ll*pg[i]*a.sc+a.fs)%mod;
}
// Pt(ans);
// printf("Part 2 is over!");
while(m--) {
int x=read(),y=read();
if(x>y) swap(x,y);
if(x==y){ Pt(ans);continue;}
Pli a1=ask(1,1,n,x+1,y,1,pl[x]-1),
a2=ask(1,1,n,x+1,y,pl[x]+1,n),
b1=ask(1,1,n,x+1,y-1,1,pl[y]-1),
b2=ask(1,1,n,x+1,y-1,pl[y]+1,n);
// printf("Part 3 unit 1 is over!\n");
ans=(ans+(1ll*pg[x]*a2.sc+a2.fs)%mod-(1ll*pg[x]*a1.sc+a1.fs)%mod)%mod;
ans=(ans+(1ll*pg[y]*b1.sc+b1.fs)%mod-(1ll*pg[y]*b2.sc+b2.fs)%mod)%mod;
insert(1,1,n,x,pl[x],pg[x],-1);
insert(1,1,n,x,pl[y],pg[y],1);
insert(1,1,n,y,pl[y],pg[y],-1);
insert(1,1,n,y,pl[x],pg[x],1);
if(ans<0) ans+=mod;
Pt(ans);swap(pl[x],pl[y]);swap(pg[x],pg[y]);
}
return 0;
}