HDU 4879 ZCC loves march

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
将每次的移动,看做是一个新的点的诞生,合并使用并查集,用两个map套个容器就可以了。

#include<map> 
#include<set>
#include<ctime>  
#include<cmath>      
#include<queue>   
#include<string>  
#include<vector>  
#include<cstdio>      
#include<cstring>    
#include<iostream>  
#include<algorithm>      
#include<functional>  
using namespace std;
#define ms(x,y) memset(x,y,sizeof(x))      
#define rep(i,j,k) for(int i=j;i<=k;i++)      
#define per(i,j,k) for(int i=j;i>=k;i--)      
#define loop(i,j,k) for (int i=j;i!=-1;i=k[i])      
#define inone(x) scanf("%d",&x)      
#define intwo(x,y) scanf("%d%d",&x,&y)      
#define inthr(x,y,z) scanf("%d%d%d",&x,&y,&z)    
#define infou(x,y,z,p) scanf("%d%d%d%d",&x,&y,&z,&p)   
#define lson x<<1,l,mid  
#define rson x<<1|1,mid+1,r  
#define mp(i,j) make_pair(i,j)  
#define ft first  
#define sd second  
typedef long long LL;
typedef pair<LL, LL> pii;
const int low(int x) { return x&-x; }
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
const double eps = 1e-10;
int T, n, m, fa[N], cnt[N], sz, g[N], o;
LL d;
pii a[N];
map<LL, set<int>> x, y;
char s[N];

int get(int x) { return x == fa[x] ? x : fa[x] = get(fa[x]); }

int main()
{
	while (~scanf("%d%lld", &n, &d))
	{
		for (auto i : x) i.second.clear();
		for (auto i : y) i.second.clear(); 
		x.clear(); y.clear();
		rep(i, 1, n)
		{
			cnt[i] = 1; fa[i] = g[i] = i;
			scanf("%lld%lld", &a[i].ft, &a[i].sd);
			x[a[i].ft].insert(i); y[a[i].sd].insert(i);
		}
		sz = n;
		inone(m);
		int last = 0, ans;
		while (m--)
		{
			scanf("%s", s);
			inone(o); o = o^last;
			int fo = get(g[o]);
			if (s[0] == 'Q')
			{
				ans = 0;
				for (auto i : x[a[fo].ft])
				{
					if (i == fo) continue;
					LL q = (a[i].sd - a[fo].sd) % mod;
					ans = (q * q % mod * cnt[i] + ans) % mod;
					cnt[fo] += cnt[i]; fa[i] = fo; cnt[i] = 0;
				}
				for (auto i : y[a[fo].sd])
				{
					if (i == fo) continue;
					LL q = (a[i].ft - a[fo].ft) % mod;
					ans = (q * q % mod * cnt[i] + ans) % mod;
					cnt[fo] += cnt[i]; fa[i] = fo; cnt[i] = 0;
				}
				x[a[fo].ft].clear(); x[a[fo].ft].insert(fo);
				y[a[fo].sd].clear(); y[a[fo].sd].insert(fo);
				printf("%d\n", last = ans); continue;
			}
			scanf("%lld", &d);
			++sz;
			cnt[sz] = 1; fa[sz] = sz; cnt[fo]--; 
			a[sz] = a[fo]; g[o] = sz;
			if (s[0] == 'L' || s[0] == 'R') a[sz].sd += s[0] == 'L' ? -d : d;
			else a[sz].ft += s[0] == 'U' ? -d : d;
			x[a[sz].ft].insert(sz);
			y[a[sz].sd].insert(sz);
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值