【模拟+hash+并查集】2014 Multi-University Training Contest 2|HDU_4879 ZCC loves march
2014-07-26 19:10
429 查看
原题直通车:HDU_4879 ZCC loves march
题意概述:在m*m(m<=10^18)的矩阵中有n(n<=10^5)个数(1~n),有k(k<=10^5)次操作,有以下两种操作:
1、将一个数i在同一行或同一列上移动d个单位
2、将与数i在同一行或同一列的所有数都移到i所在的位置,并输出所有(xi-xj)^2+(yi-yj)^2的和
分析:
1、因为只有移动和操作,所以占用到的坐标数最多为n+k个,所以用一个map将每个坐标映射到一个数。
2、对于操作2,为了便于查到每一行、每一列中有多少个数,所以用map映射到每一行、列分别一个set集合
3、放到每个set集合中的并不是n个数,而是每一个坐标的映射,因为每个坐标可能有多个数,但映射只有一个(理论上是),只要记录每个坐标上有多少个数即可,因为结果只与坐标有关,与n个数无关,以此避免TLE和MLE。
4、一个数只对应一个坐标,移动的时候,可以直接看成坐标的变化,也就是对应坐标映射的变化,所以只需用一个next数据记录移动的位置,数的数量直接相加即可。
5、虽然经过操作2之后,坐标中已经没有数了,但是后面可能会用到相应的next,所以经过了操作2的坐标要重新开辟一个映射,才不会和后面进行操作1时移动到这种坐标的数相应的next冲突。
附:2014 Multi-University Training Contest 2--by 镇海中学
解题报告
参考代码:
题意概述:在m*m(m<=10^18)的矩阵中有n(n<=10^5)个数(1~n),有k(k<=10^5)次操作,有以下两种操作:
1、将一个数i在同一行或同一列上移动d个单位
2、将与数i在同一行或同一列的所有数都移到i所在的位置,并输出所有(xi-xj)^2+(yi-yj)^2的和
分析:
1、因为只有移动和操作,所以占用到的坐标数最多为n+k个,所以用一个map将每个坐标映射到一个数。
2、对于操作2,为了便于查到每一行、每一列中有多少个数,所以用map映射到每一行、列分别一个set集合
3、放到每个set集合中的并不是n个数,而是每一个坐标的映射,因为每个坐标可能有多个数,但映射只有一个(理论上是),只要记录每个坐标上有多少个数即可,因为结果只与坐标有关,与n个数无关,以此避免TLE和MLE。
4、一个数只对应一个坐标,移动的时候,可以直接看成坐标的变化,也就是对应坐标映射的变化,所以只需用一个next数据记录移动的位置,数的数量直接相加即可。
5、虽然经过操作2之后,坐标中已经没有数了,但是后面可能会用到相应的next,所以经过了操作2的坐标要重新开辟一个映射,才不会和后面进行操作1时移动到这种坐标的数相应的next冲突。
附:2014 Multi-University Training Contest 2--by 镇海中学
解题报告
参考代码:
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<set> using namespace std; const int maxn = 1e5+100; const int mod = 1e9+7; int fa[maxn], num[maxn<<1], next[maxn<<1]; long long x[maxn<<1], y[maxn<<1]; typedef long long LL; typedef pair<LL, LL> pl; typedef map< pl, int > map_pl; typedef map< LL, set<int> > map_LL; typedef pair< map_LL::iterator, map_LL::iterator > pll; map_LL mx, my; map_pl M; int n; LL m, len, ans, d; void Input() { for(int i=1; i<=n; ++i) { long long xx, yy; scanf("%I64d%I64d", &xx, &yy); pl p = make_pair(xx, yy); if(M[p] == 0) { x[len] = xx, y[len] = yy, num[len] = 0, next[len] = len; pll px = mx.equal_range(xx), py = my.equal_range(yy); if(px.first == px.second) { set<int>s; mx[xx] = s; } //还没有映射的集合 if(py.first == py.second) { set<int>s; my[yy] = s; } mx[xx].insert(len), my[yy].insert(len); M[p] = len++; } num[M[p]]++; fa[i] = M[p]; } } int get_end(int rt) { //寻找最终的移动位置 return next[rt] == rt ? rt : (next[rt] = get_end(next[rt])); } int main() { while(~scanf("%d%I64d", &n, &m)) { len = 1, ans = 0; mx.clear(), my.clear(), M.clear(); Input(); int k, o; scanf("%d", &k); while(k--) { char op[5]; scanf("%s%d", op, &o); o ^= ans; int rt = get_end(fa[o]); fa[o] = rt; //指向移动的位置 pl p = make_pair(x[rt], y[rt]); if(op[0] == 'Q') { ans = 0; set<int>sx = mx[x[rt]], sy = my[y[rt]]; //同行、同列的坐标 set<int>::iterator it; for(it=sx.begin(); it!=sx.end(); ++it) if((*it) != rt) { int ne = get_end(*it); long long u = (y[ne] - y[rt] + mod) % mod; u = ( (u * u)%mod )*num[ne] %mod; ans = (ans + u) % mod; my[y[ne]].erase(ne); num[rt] += num[ne], num[ne] = 0, next[ne] = rt; M[make_pair(x[ne], y[ne])] = 0; // 对应的位置不能再用,因为可能有其它的next指向这里 } for(it=sy.begin(); it!=sy.end(); ++it) if((*it) != rt) { int ne = get_end(*it); long long u = (x[ne] - x[rt] + mod) % mod; u = ( (u * u)%mod )*num[ne] %mod; ans = (ans + u) % mod; my[x[ne]].erase(ne); num[rt] += num[ne], num[ne] = 0, next[ne] = rt; M[make_pair(x[ne], y[ne])] = 0; // 对应的位置不能再用,因为可能有其它的next指向这里 } printf("%I64d\n", ans); continue; } scanf("%I64d", &d); long long xx = x[rt], yy = y[rt]; if(op[0] == 'U') xx -= d; if(op[0] == 'D') xx += d; if(op[0] == 'L') yy -= d; if(op[0] == 'R') yy += d; num[rt]--; p = make_pair(xx, yy); if(M[p] == 0) { x[len] = xx, y[len] = yy, num[len] = 0, next[len] = len; M[p] = len++; } fa[o] = M[p]; //o被移动到M[p]坐标,直接改变坐标指向 num[M[p]]++; } } return 0; }
相关文章推荐
- Hdu4882 - ZCC Loves Codefires - 贪心(2014 Multi-University Training Contest 2-1011)
- 2014 Multi-University Training Contest 2 ZCC loves cards
- hdu 4876 ZCC loves cards 2014 Multi-University Training Contest 2
- hdu4882 ZCC Loves Codefires 2014 Multi-University Training Contest 2
- 2014 Multi-University Training Contest 2---ZCC Loves Codefires
- 2014 Multi-University Training Contest 2 1011 ZCC Loves Codefires 解题报告
- 2014 Multi-University Training Contest 2 ZCC loves cards
- 【2014 Multi-University Training Contest 2 1002】/【HDU 4873】 ZCC Loves Intersection
- 【2014 Multi-University Training Contest 2 1002】/【HDU 4873】 ZCC Loves Intersection
- 【2014 Multi-University Training Contest 2 1002】/【HDU 4873】 ZCC Loves Intersection
- 【贪心】【2014 Multi-University Training Contest 2】1011 ZCC Loves Codefires
- 【2014 Multi-University Training Contest 2 1002】 ZCC Loves Intersection
- 【暴力+优化】【2014 Multi-University Training Contest 2】ZCC loves cards
- 2014 Multi-University Training Contest 2 - 1011 / hdu 4882 ZCC Loves Codefires
- 【2014 Multi-University Training Contest 6】 J. Fighting the Landlords(模拟)
- 2014 Multi-University Training Contest 1 - J Rating
- (HDU 5818)2016 Multi-University Training Contest 7 Joint Stacks (模拟、stack)
- 2017 Multi-University Training Contest 3 && HDOJ 6058 Kanade's sum 【链表模拟】
- hdu 4946 2014 Multi-University Training Contest 8
- HDU 4864 Task(2014 Multi-University Training Contest 1) 贪心算法