每个点如果不考虑被分裂出去,他至多只会被合并一次,维护两个set,每次合并可以暴力找出这一行/列的所有点,并查集资瓷一下合并成一个点,每次分裂可以直接新建一个点代表这个分出去的点
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e18+1
using namespace std;
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
const ll Mod = 1e9+7;
ll sqr(ll x){x=x%Mod;return x*x%Mod;}
const int maxn = 410000;
char to[1100];
int n,m;
int tru[maxn];
int num[maxn],fa[maxn];
int findfa(const int x){return fa[x]==x?x:fa[x]=findfa(fa[x]);}
struct nodex
{
ll x,y;int i;
friend inline bool operator <(const nodex aa,const nodex b)
{
return aa.x==b.x?aa.y<b.y:aa.x<b.x;
}
}a[maxn];
multiset<nodex>Sx;
multiset<nodex>::iterator itx,itx2;
struct nodey
{
ll x,y;int i;
friend inline bool operator <(const nodey aa,const nodey b)
{
return aa.y==b.y?aa.x<b.x:aa.y<b.y;
}
};
multiset<nodey>Sy;
multiset<nodey>::iterator ity,ity2;
int lastans;
char str[110];
int main()
{
to['U']=0,to['R']=1,to['D']=2,to['L']=3;
scanf("%d%*lld",&n);
for(int i=1;i<=n;i++)
{
ll x,y; scanf("%lld%lld",&x,&y);
a[i].x=x; a[i].y=y; a[i].i=i; tru[i]=i;
num[i]=1,fa[i]=i;
Sx.insert((nodex){x,y,i});
Sy.insert((nodey){x,y,i});
}
scanf("%d",&m);
while(m--)
{
scanf("%s",str);
if(str[0]=='Q')
{
int x; scanf("%d",&x); x=tru[x^lastans]; lastans=0;
int ff=findfa(x);
a[++n]=a[ff]; a[n].i=n;
num[n]=num[ff]; num[ff]=0; fa[ff]=fa[n]=n;
nodex tmpx=(nodex){a[ff].x-1,inf};
itx=Sx.lower_bound(tmpx);
while(itx!=Sx.end())
{
itx2=itx; itx2++;
if((*itx).x!=a[ff].x) break;
int ii=(*itx).i;
if(findfa(ii)==ii)
{
fa[ii]=n; num[n]+=num[ii];
(lastans+=sqr((*itx).y-a[ff].y)*num[ii]%Mod)%=Mod;
num[ii]=0;
}
Sx.erase(itx); itx=itx2;
}
nodey tmpy=(nodey){inf,a[ff].y-1};
ity=Sy.lower_bound(tmpy);
while(ity!=Sy.end())
{
ity2=ity; ity2++;
if((*ity).y!=a[ff].y) break;
int ii=(*ity).i;
if(findfa(ii)==ii)
{
fa[ii]=n; num[n]+=num[ii];
(lastans+=sqr((*ity).x-a[ff].x)*num[ii]%Mod)%=Mod;
num[ii]=0;
}
Sy.erase(ity); ity=ity2;
}
Sx.insert(a[n]);
Sy.insert((nodey){a[n].x,a[n].y,a[n].i});
printf("%d\n",lastans);
}
else
{
int k=to[str[0]];
int x; ll d; scanf("%d%lld",&x,&d);
int y=x^lastans; x=tru[y];
int ff=findfa(x);
num[tru[y]=++n]=1,fa[n]=n;
a[n]=a[ff]; a[n].i=n;
a[n].x+=d*dx[k],a[n].y+=d*dy[k];
Sx.insert(a[n]);
Sy.insert((nodey){a[n].x,a[n].y,a[n].i});
num[ff]--;
if(!num[ff]) fa[ff]=0;
}
}
return 0;
}