hdu 4879 ZCC loves march

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.
 

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. 
 

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 7
Hint
The 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值