题意略
算法:
由于地图范围m*m很大,m<=10^18,求军队的个数n也很大有10^5。
如果只是简单的每个点按照操作模拟就可能超时。
---->比赛的时候就因为这样大的数据没有深入的想,其实只要再进一步就可以了
用一个set来维护每行和每列的军队编号。
Q操作合并后很多点都在一起,那么后来 又有合并移动操作时,就把这些所有的点都当做一个点,
这样操作次数就会大大减少。
由于合并堆中的某些点可能单独移动,用并查集维护。
乘法运算可能超过long long,要记得取模。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 200000+5;
const int mod = 1000000000+7;
struct Node
{
ll x,y;
int num;
Node(){}
Node(ll x,ll y,int num)
{
this->x = x;
this->y = y;
this->num = num;
}
};
map<ll,set<int> > Mx,My;
set<int>::iterator iter;
int cnt,n,fa[maxn];
ll m;
Node pos[maxn];
int find(int x)
{
return fa[x]==x?x:find(fa[x]);
}
int main()
{
ll a,b;
int t;
while(scanf("%d%I64d",&n,&m)!=EOF)
{
Mx.clear();
My.clear();
for(int i=1;i<=n;i++)
{
scanf("%I64d%I64d",&a,&b);
pos[i] = Node(a,b,1);
Mx[a].insert(i);
My[b].insert(i);
fa[i] = i;
}
cnt = n+1;
ll lasten = 0;
scanf("%d",&t);
while(t--)
{
int x;
char str[5];
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d",&x);
x = x^lasten;
int p = find(x);
int total = 0;
lasten = 0; //
ll xx,yy;
Node cur;
xx = pos[p].x,yy = pos[p].y;
for(iter = Mx[xx].begin();iter!=Mx[xx].end();iter++)
{
cur = pos[*iter];
ll col = cur.y;
My[col].erase(*iter);
total += cur.num;
ll dis = abs(col-yy)%mod;
lasten = (lasten + (dis*dis)%mod*cur.num)%mod;
fa[*iter] = cnt;
}
for(iter = My[yy].begin();iter!=My[yy].end();iter++)
{
cur = pos[*iter];
ll ros = cur.x;
My[ros].erase(*iter);
total += cur.num;
ll dis = abs(ros-xx)%mod;
lasten = (lasten + (dis*dis)%mod*cur.num)%mod;
fa[*iter] = cnt;
}
fa[cnt] = cnt;
pos[cnt] = Node(xx,yy,total);
Mx[xx].clear();
My[yy].clear();
Mx[xx].insert(cnt);
My[yy].insert(cnt);
cnt++;
printf("%I64d\n",lasten);
}
else
{
int x;
ll d;
scanf("%d%I64d",&x,&d);
x = x^lasten;
int p = find(x);
pos[p].num--;
ll nx = pos[p].x,ny = pos[p].y;
if(pos[p].num==0)
{
Mx[nx].erase(p);
My[ny].erase(p);
}
if(str[0]=='L')
ny -= d;
else if(str[0]=='R')
ny += d;
else if(str[0]=='U')
nx -= d;
else if(str[0]=='D')
nx += d;
pos[x] = Node(nx,ny,1);
fa[x] = x;
Mx[nx].insert(x);
My[ny].insert(x);
}
}
}
return 0;
}