HDU 4879 ZCC loves march (并查集,set,map)

题面以及思路:https://blog.csdn.net/glqac/article/details/38402101

代码:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL mod = 1000000007;
const int maxn = 2000010;
struct node {
	LL x, y;
	int cnt;
	node(){}
	node(LL x, LL y, int cnt) {
		this -> x = x;
		this -> y = y;
		this -> cnt = cnt;
	}
};
node pos[maxn];
map<LL, set<int> > row, col;
set<int> :: iterator it;
int f[maxn];
int get(int x) {
	if(x == f[x]) return x;
	return f[x] = get(f[x]);
}
int tot;
int main() {
	int n, m, T, p;
	LL x, y, ans, d;
	char s[10];
	while(~scanf("%d%d", &n, &m)) {
		row.clear();
		col.clear();
		for (int i = 1; i <= n; i++) {
			scanf("%lld%lld", &x, &y);
			pos[i] = node(x, y, 1);
			f[i] = i;
			row[x].insert(i);
			col[y].insert(i);
		}
		f[n + 1] = n + 1;
		tot = n + 1;
		scanf("%d", &T);
		ans = 0;
		while(T--) {
			scanf("%s",s + 1);
			if(s[1] == ‘Q‘) {
				scanf("%d", &p);
				p = p ^ ans;
				p = get(p);
				node tmp = pos[p];
				int num = 0;
				ans = 0;
				LL xx = pos[p].x, yy = pos[p].y;
				for (it = row[xx].begin(); it != row[xx].end(); it++) {
					node& tmp = pos[*it];
					f[*it] = tot;
					col[yy].erase(*it);
					num += tmp.cnt;
					LL tmp1 = (abs(yy - tmp.y)) % mod;
					ans = (ans + (tmp1 * tmp1) % mod * tmp.cnt % mod) % mod;
					tmp.y = yy;
				}
				for (it = col[yy].begin(); it != col[yy].end(); it++) {
					node& tmp = pos[*it];
					f[*it] = tot;
					num += tmp.cnt;
					row[xx].erase(*it);
					LL tmp1 = (abs(xx - tmp.x)) % mod;
					ans = (ans + (tmp1 * tmp1) % mod) % mod;
					tmp.y = yy;
				}
				col[yy].clear();
				row[xx].clear();
				pos[tot] = node(xx, yy, num);
				col[yy].insert(tot);
				row[xx].insert(tot);
				tot++;
				f[tot] = tot;
				printf("%lld\n", ans);
			} else {
				scanf("%d%lld", &p, &d);
				p = p ^ ans;
				int p1 = p;
				p = get(p);
				node& tmp = pos[p];
				LL xx = tmp.x, yy = tmp.y;
				tmp.cnt--;
				if(tmp.cnt == 0) {
					row[xx].erase(p);
					col[yy].erase(p);
				}
				if(s[1] == ‘L‘) {
					yy -= d;
				} else if(s[1] == ‘U‘) {
					xx -= d;
				} else if(s[1] == ‘D‘) {
					xx += d;
				} else {
					yy += d;
				}
				f[p1] = p1;
				pos[p1] = node(xx, yy, 1);
				row[xx].insert(p1);
				col[yy].insert(p1);
			}
		}
	}

}

  

原文地址:https://www.cnblogs.com/pkgunboat/p/10547905.html

时间: 2024-10-14 20:58:04

HDU 4879 ZCC loves march (并查集,set,map)的相关文章

HDU 4879 ZCC loves march(并查集+set)

题意:一个最大10^18*10^18的矩阵,给你最多十万个士兵的位置,分别分布在矩阵里,可能会位置重复,然后有2种操作,一种是把第i个士兵向上下左右移动,另一种是把第i个士兵与他横坐标纵坐标相同的士兵全部移到这个点上,然后要计算花费. 这道题我想了好几天.在看了标程得到一些提示后总算写出来了.加了读入优化后快了100ms左右达到546ms. 做法:开2个set分别维护X相同的和Y相同的,但是会有相同位置点的坐标,该怎么办?用并查集去维护相同位置的点,读入的时候就可能会有位置相同的点,所以读的时候

HDU 4879 ZCC loves march (2014多校2-1008,数据结构,STL,模拟题)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=4879 题意: 给一个n*m的矩阵,有n个人,t次操作,操作有以下两种: 1.令编号x的人上下左右移动 2.令与编号x的人同行同列的人聚集到x这里,输出花费 方法: 使用两个set,一个维护x轴,一个维护y轴 一个map<point,int>,表示这一个point有多少个人 然后根据要求的操作直接操作即可,nlgn复杂度 注意: 1.由于set或者map是红黑树,所以删除节点的后,内部节点重排,it+

hdu 4882 ZCC Loves Codefires(数学题+贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4882 ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

HDU 4873 ZCC Loves Intersection(JAVA、大数、推公式)

在一个D维空间,只有整点,点的每个维度的值是0~n-1 .现每秒生成D条线段,第i条线段与第i维度的轴平行.问D条线段的相交期望. 生成线段[a1,a2]的方法(假设该线段为第i条,即与第i维度的轴平行)为,i!=j时,a1[j]=a2[j],且随机取区间[0,n-1]内的整数.然后a1[i],a2[i]在保证a1[i]<a2[i]的前提下同样随机. 由于D条线段各自跟自己维度的轴平行,我们可以转换成只求第i个维度与第j个维度的相交期望,然后乘以C(2,n)就好了 显然线段[a1,a2]和线段[

HDU 4876 ZCC loves cards _(:зゝ∠)_ 随机输出保平安

GG,,,g艹 #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <queue> #include <math.h> using namespace std; vector<int>G[21][7];//G[i][j] 表示n=i k=j的情况下 二进

hdu 4882 ZCC Loves Codefires(贪心)

# include<stdio.h> # include <algorithm> # include <string.h> using namespace std; struct node { int v; int t; }; struct node a[100010]; bool cmp(node a,node b) { return a.v *a.t+(a.v+b.v)*b.t<b.v*b.t+(a.v+b.v)*a.t; } int main() { int

HDU 3635 延缓更新的并查集

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2839    Accepted Submission(s): 1097 Problem Description Five hundred years later, the number of dragon balls will increase unexpecte

JAVA hdu 4882 ZCC Loves Codefires

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4882 题解:参考题后Discuss javaherongwei 的讲解 考察序列中相邻的两题i, j(i在前).交换它们后,解出它们之前的题目所带来的时间对答案的贡献是不变的,它们对它们后面的题目的贡献也是不变的,其他题目之间对答案的贡献自然也是不变的.唯一的变化就是,原来的EiKj一项变成了EjKi一项.那么,为了使答案变优,需要满足的条件是EjKi≤EiKj.也即Ei/Ki≥Ej/Kj.那么,最

HDU 4876 ZCC loves cards

我决定记录下这么恶心的代码.比赛的时候头晕脑胀,写得好搓,错的地方好多好多,回来调了好久.... 做法大概就是C(20,6)选出卡牌后,再k!枚举排列,再k*k得出该排列能得出什么数字. 当然,光这样做绝对会T,里面加了各种剪枝后就1650ms险过了.. 最主要的剪枝是选出k张牌后,看牌能不能组成L~ans里面各个数字,能才进行下一步.然后k!可以拆成(k-x)!*(x!)..不过这里其实大概没什么大优化吧 #include<cstdio> #include<iostream> #