ZCC loves march
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 130712/130712 K (Java/Others)Total Submission(s): 445 Accepted Submission(s): 87
Problem Description
On a m*m land stationed n troops, numbered from 1 to n. The i-th troop's position can be described by two numbers (xi,yi) (1<=xi<=m,1<=yi<=m). It is possible that more than one troop stationed in the same place.
Then there are t minutes, in each minute one of the following two events will occur:
(1)the x-th troop moves towards a direction( Up(U) Down(D) Left(L) Right(R))for d units;(You can suppose that the troops won't move out of the boundary)
(2)the x-th troop needs to regroup the troops which stations in the same row or column with the x-th troop. That is, these troops need to move to the x-th troop's station.
Suggest the cost of i-th troop moving to the j-th troop is (xi-xj)^2+(yi-yj)^2, every time a troop regroups, you should output the cost of the regrouping modulo 10^9+7.
Then there are t minutes, in each minute one of the following two events will occur:
(1)the x-th troop moves towards a direction( Up(U) Down(D) Left(L) Right(R))for d units;(You can suppose that the troops won't move out of the boundary)
(2)the x-th troop needs to regroup the troops which stations in the same row or column with the x-th troop. That is, these troops need to move to the x-th troop's station.
Suggest the cost of i-th troop moving to the j-th troop is (xi-xj)^2+(yi-yj)^2, every time a troop regroups, you should output the cost of the regrouping modulo 10^9+7.
Input
The first line: two numbers n,m(n<=100000,m<=10^18)
Next n lines each line contain two numbers xi,yi(1<=xi,yi<=m)
Next line contains a number t.(t<=100000)
Next t lines, each line's format is one of the following two formats:
(1)S x d, S∈{U,L,D,R}, indicating the first event(1<=x<=n,0<=d<m)
(2)Q x, indicating the second event(1<=x<=n)
In order to force you to answer the questions online, each time you read x', x=x'⊕lastans("⊕" means "xor"), where lastans is the previous answer you output. At the beginning lastans=0.
Next n lines each line contain two numbers xi,yi(1<=xi,yi<=m)
Next line contains a number t.(t<=100000)
Next t lines, each line's format is one of the following two formats:
(1)S x d, S∈{U,L,D,R}, indicating the first event(1<=x<=n,0<=d<m)
(2)Q x, indicating the second event(1<=x<=n)
In order to force you to answer the questions online, each time you read x', x=x'⊕lastans("⊕" means "xor"), where lastans is the previous answer you output. At the beginning lastans=0.
Output
Q lines, i-th line contain your answer to the i-th regrouping event.(modulo 10^9+7)
Sample Input
5 3 1 3 2 1 2 2 2 3 3 2 6 Q 1 L 0 2 L 5 2 Q 5 R 3 1 Q 3
Sample Output
1 1 7HintThe input after decode: Q 1 L 1 2 L 4 2 Q 4 R 2 1 Q 2
set里存某一行某一列的点的编号,外面套map。然后一个优化的地方是,当Q操作之后,很多点都聚在了一起,可以把它们处理成一个点,以后Q移动时,就只用移动这个点。因为当中某些点可能会单独移动,用并查集实现。注意乘积时可能超longlong。
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<stack>
#include<iostream>
#include<queue>
#include<cmath>
#include<string>
#include<set>
#include<map>
using namespace std;
const int maxn = 200000 + 5;
const int INF = 1000000000;
const int Mod = 1000000000 + 7;
typedef long long LL;
typedef pair<LL, LL> P;
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 it;
int fa[maxn];
Node pos[maxn];
int cnt;
int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
int main(){
int n, m;
//freopen("1008.in", "r", stdin);
//freopen("out.txt", "w", stdout);
while(scanf("%d%d", &n, &m) != EOF){
Mx.clear();
My.clear();
for(int i = 1;i <= n;i++){
LL x, y;
scanf("%I64d%I64d", &x, &y);
pos[i] = Node(x, y, 1);
fa[i] = i;
Mx[x].insert(i);
My[y].insert(i);
}
cnt = n+1;
int t;
scanf("%d", &t);
LL lastans = 0;
while(t--){
char str[5];
scanf("%s", str);
if(str[0]=='Q'){
int x;
scanf("%d", &x);
x = x^lastans;
int X = Find(x);
Node& tem = pos[X];
LL row = tem.x;
LL col = tem.y;
int num = tem.num;
lastans = 0;
int total = 0;
for(it = Mx[row].begin();it != Mx[row].end();it++){
Node& tem = pos[*it];
LL y = tem.y;
My[y].erase(*it);//提前消掉了y里的 X
int num = tem.num;
LL der = abs(y-col)%Mod;
lastans = (lastans + (der*der)%Mod * num) % Mod;
fa[*it] = cnt;
total += num;
}
for(it = My[col].begin();it != My[col].end();it++){
Node& tem = pos[*it];
LL x = tem.x;
Mx[x].erase(*it);
int num = tem.num;
LL der = (abs(x-row))%Mod;
lastans = (lastans + (der*der)%Mod*num) % Mod;
fa[*it] = cnt;
total += num;
}
fa[cnt] = cnt;
pos[cnt] = Node(row, col, total);
Mx[row].clear();
My[col].clear();
Mx[row].insert(cnt);
My[col].insert(cnt);
cnt++;
printf("%I64d\n", lastans);
}
else{
int x;
LL d;
scanf("%d%I64d", &x, &d);
x = x^lastans;
int X = Find(x);
Node& tem = pos[X];
LL nx = tem.x;
LL ny = tem.y;
tem.num--;
if(tem.num==0){
Mx[nx].erase(X);
My[ny].erase(X);
}
if(str[0]=='U'){
nx -= d;
}
else if(str[0]=='L'){
ny -= d;
}
else if(str[0]=='D'){
nx += d;
}
else{
ny += d;
}
fa[x] = x;
pos[x] = Node(nx, ny, 1);
Mx[nx].insert(x);
My[ny].insert(x);
}
}
}
return 0;
}