Clarke and hunger games

 Accepts: 2
 Submissions: 54
 Time Limit: 6000/3000 MS (Java/Others)
 Memory Limit: 65536/65536 K (Java/Others)

问题描述
克拉克是一名人格分裂患者。某一天,克拉克fork出了很多个克拉克,居住在nn个社区里。
克拉克由于自己的抖M属性,所以克拉克们决定玩饥饿游戏。
由于克拉克们住在天空之城中,所以他们相互联系靠的是社区之间的桥。
克拉克是非常节约的,两个社区能相互可达时只有一条路径,这样就节约了不少金钱。
饥饿游戏的规则是这样的:每一个社区选出两个人,然后作为供品去参加死亡比赛,最终活下一个人,并终身获得自由,获得无限的荣誉和金钱。
克拉克们想知道选出的人中有多少种组合。两个组合相同当且仅当选出的人都相同。
由于克拉克的抖M属性,克拉克还有qq次操作:
1 \ u \ v1 u v:在u, vu,v两个社区之间建桥。如果u, vu,v已经有路径或u=vu=v相连则忽略。
2 \ u \ v2 u v:删除u, vu,v两个社区的之间的桥。如果u, vu,v之间没有桥或u=vu=v则忽略。
3 \ h3 h:变回到第hh次操作后的状态,当h=0h=0时表示回到初始状态,即社区之间是没有桥的。
4 \ u \ v4 u v:询问uu到vv路径上的所有社区(包括uu和vv)每个社区选出人参加比赛的方案数(如果不存在路径输出00),由于方案数太多,所以求出对10^9+710​9​​+7取模的答案。
5 \ u \ s5 u s:社区uu中的克拉克的数量变为ss。
一开始克拉克的社区之间是没有桥的。  
输入描述
第一行一个整数T(1 \le T \le 5)T(1≤T≤5),表示数据的组数。
每组数据第一行有两个整数n, q(1 \le n, q \le 3*10^5)n,q(1≤n,q≤3∗10​5​​)。
第二行有nn个整数,第ii个数a_i(0 \le a_i \le 10^4)a​i​​(0≤a​i​​≤10​4​​)表示第ii个社区的人数。
接下来qq行,第ii个询问的第一个数为optopt。
当opt=1opt=1时,后面接着两个整数u_i, v_iu​i​​,v​i​​。
当opt=2opt=2时,后面接着两个整数u_i, v_iu​i​​,v​i​​。
当opt=3opt=3时,后面接着一个整数h_ih​i​​。
当opt=4opt=4时,后面接着两个整数u_i, v_iu​i​​,v​i​​。
当opt=5opt=5时,后面接着两个整数u_i, s_iu​i​​,s​i​​。
1 \le u_i, v_i \le n, 0 \le h_i < i, 0 \le s_i \le 10^41≤u​i​​,v​i​​≤n,0≤h​i​​<i,0≤s​i​​≤10​4​​
输出描述
对于每组数据的opt=4opt=4,输出一个整数表示答案。  
输入样例
1
3 5
1 2 3
1 1 2
2 1 2
3 1
5 1 3
4 1 2
输出样例
3

lct,对于回退操作,直接暴力处理,建立一棵操作树,每个操作最多正着,反着执行一次,时间复杂度为2nlog(n)

#include <iostream>
#include <cstdio>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;#define LL __int64
#define LS(x) node[(x)].ch[0]
#define RS(x) node[(x)].ch[1]
#define P pair<int ,int>
#define X first
#define Y second
#define PB push_backconst int N = 3 * 1e5 + 5;const int MOD = 1000000007;int a[N];set<P> used;
set<P>::iterator it;struct LCT {struct Node {int fa, ch[2];bool rev;int size;void init(LL x) {fa = 0;rev = ch[0] = ch[1] = 0;size = (LL)x * (x - 1) / 2;}} node[N];bool is_root(int x) {return (LS(node[x].fa) != x && RS(node[x].fa) != x);}void down(int x) {if(node[x].rev) {node[LS(x)].rev ^= 1;node[RS(x)].rev ^= 1;swap(LS(x), RS(x));node[x].rev = 0;}}void up(int x) {node[x].size = (LL)a[x] * (a[x] - 1) / 2 * node[LS(x)].size % MOD * node[RS(x)].size % MOD;}void rotate(int x, bool kind) {int fx = node[x].fa;int ffx = node[fx].fa;node[fx].ch[!kind] = node[x].ch[kind];node[node[x].ch[kind]].fa = fx;if(!is_root(fx))node[ffx].ch[RS(ffx) == fx] = x;node[x].fa = ffx;node[x].ch[kind] = fx;node[fx].fa = x;up(fx);}int d_st[N], ds_top;void splay(int x) {ds_top = -1;d_st[++ds_top] = x;for(int i = x; !is_root(i); i = node[i].fa)d_st[++ds_top] = node[i].fa;for(int i = ds_top; i >= 0 ; --i) down(d_st[i]);while(!is_root(x)) {int fx = node[x].fa;int ffx = node[fx].fa;bool rot_x = (LS(fx) == x);bool rot_fx = (LS(ffx) == fx);if(is_root(fx)) rotate(x, rot_x);else {if(rot_x == rot_fx) rotate(fx, rot_fx);else rotate(x, rot_x);rotate(x, rot_fx);}}up(x);}void access(int x) {int last = 0;while(x) {splay(x);RS(x) = last;last = x;x = node[x].fa;}}//access(x); splay(x); 后x在根的位置,此时x只有左子树,没有右子树,打翻转标记就是使得左子树变到右子树上。void make_root(int x) {access(x); splay(x);node[x].rev ^= 1;}int find(int x) {access(x); splay(x);while(LS(x)) x = LS(x);return x;}bool cut(int x, int y) {if(x > y) swap(x, y);it = used.find(P(x, y));if(it == used.end()) return false;make_root(x);access(y); splay(y);LS(y) = node[x].fa = 0;up(y);used.erase(it);return true;}bool link(int x, int y) {if(x > y) swap(x, y);int fx = find(x);int fy = find(y);if(fx == fy) return false;make_root(x);node[x].fa = y;used.insert(P(x, y));return true;}void init(int n) {for(int i = 0; i <= n; ++i)node[i].init(a[i]);node[0].size = 1;}void debug(int n) {for(int i = 0; i <= n; ++i) {cout<<i<<": "<<node[i].size<<' '<<node[i].fa<<' '<<node[i].ch[0]<<' '<<node[i].ch[1]<<endl;}}int get_ans(int x, int y) {int fx = find(x);int fy = find(y);if(fx != fy) return 0;make_root(x);access(y); splay(y); return node[y].size;}void dfs(int);
} lct;vector<int> G[N];int opt[N], u[N], v[N];
vector<P> ans;void LCT::dfs(int x) {for(int i = 0; i < G[x].size(); ++i) {int y = G[x][i];if(opt[y] == 1) {bool flag = link(u[y], v[y]);dfs(y);if(flag) cut(u[y], v[y]);} else if(opt[y] == 2) {bool flag = cut(u[y], v[y]);dfs(y);if(flag) link(u[y], v[y]);} else if(opt[y] == 4) {//ans[y] = get_ans(u[y], v[y]);ans.PB(P(y, get_ans(u[y], v[y])));dfs(y);} else if(opt[y] == 5) {int tmp = a[u[y]];a[u[y]] = v[y];node[u[y]].size = (LL)v[y] * (v[y] - 1) / 2;access(u[y]); splay(u[y]);dfs(y);a[u[y]] = tmp;node[u[y]].size = (LL)tmp * (tmp - 1) / 2;access(u[y]); splay(u[y]);}}
}void gao(int n, int q) {lct.dfs(0);sort(ans.begin(), ans.end());for(int i = 0; i < ans.size(); ++i) {printf("%d\n", ans[i].Y);}
}void init(int n, int q) {lct.init(n);//lct.debug(n);for(int i = 0; i <= q; ++i) {G[i].clear();}ans.clear();used.clear();
}int main() {int T;scanf("%d", &T);while(T--) {int n, q;scanf("%d%d", &n, &q);a[0] = 0;for(int i = 1; i <= n; ++i) {scanf("%d", &a[i]);}init(n, q);int pre = 0;for(int i = 1; i <= q; ++i) {scanf("%d", &opt[i]);if(opt[i] != 3) {scanf("%d%d", &u[i], &v[i]);G[pre].PB(i);pre = i;} else {scanf("%d", &u[i]);pre = u[i];while(opt[pre] == 3) pre = u[pre];}}gao(n, q);}return 0;
}

hdu 5467 Clarke and hunger games (lct)相关推荐

  1. HDU 5465 Clarke and puzzle (二维树状数组维护区间异或)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5465 解题思路: 因为要对大量的区间进行异或,所以考虑用二维树状数组就行维护. #include< ...

  2. hdu 5563 Clarke and five-pointed star (枚举)

    题意:给出5个点的坐标,问这5个点是否刚好是一个五角星的顶点. 思路: dfs枚举5个点的顺序. 判断5条邻边相等,5条对角线相等.若均满足则是,否则不是. 附:为什么要判断5条对角线也相等才行呢? ...

  3. hdu 5465 Clarke and puzzle (二维树状数组+nim博弈)

    解析: 利用二维树状数组来区间询问异或和,以及单点更新,然后利用nim博弈的结论判断胜负. mymy codecode #include <cstdio> #include <cst ...

  4. 第十二周 11.15-11.21

    11.15 补个BC. HDU 5565 Clarke and baton 没太懂题解怎么搞.反正挺暴力过了. 1 #include <iostream> 2 #include <c ...

  5. 神经学家探寻:机器如何拥有意识!如何避免机器人伤害我们!

    来源:全球人工智能 概要:好莱坞导演们并非是对此问题困惑不解的唯一群体.随着机器智能的飞速发展,它不仅能在魔兽争霸(DOTA)和围棋这样的游戏中战胜人类玩家,而且对战过程中还不需要人类的专业知识,这一 ...

  6. 26个复古风格网站设计欣赏

    复古元素今年不断被提上来,那么今天下面分享的这26个复古元素的网页设计案例使用古典和现代的图形结合而成,还你一个不一样的复古网页设计案例,希望对你有所启发,enjoy! 你可能感兴趣的复古网站资讯: ...

  7. 2014全年目标及执行情况跟踪

    计划不能执行的一个主要原因,就是没有写下来,没有公开."写到"才能"做到",人会遗忘或假装忘掉,白纸黑字才是契约! 在2013年的年初制定了一个年度目标并跟踪记 ...

  8. 优秀HTML5网站学习范例:从“饥饿游戏浏览器”谈用户体验

    继影片<饥饿游戏>获得票房成功后,<饥饿游戏2:火星燎原>也于2012年宣布开拍,将在今年的11月22日登陆全球各大院线.值此之际,微软携手美国狮门影业公司和 RED Inte ...

  9. [kuangbin]各种各样的题单

    [kuangbin]各种各样的题单 专题1 简单搜索 POJ 1321 POJ 2251 POJ 3278 POJ 3279 POJ 1426 POJ 3126 POJ 3087 POJ 3414 F ...

  10. LeetCode MySQL 1098. 小众书籍

    文章目录 1. 题目 2. 解题 1. 题目 书籍表 Books: +----------------+---------+ | Column Name | Type | +------------- ...

最新文章

  1. 你想要的宏基因组-微生物组知识全在这(180801)
  2. 没有永远的对手只有永远的利益,浪潮与SAP合作了!
  3. 运用Smark.SocketAsyncs方便实现数据交互服务
  4. C#面向对象设计模式纵横谈
  5. 提问赠书 | 我们请了 7 位云原生专家,等你来问
  6. [BZOJ 3942] [Usaco2015 Feb] Censoring 【KMP】
  7. leetcode 191. 位1的个数(移位操作)
  8. 百度声明:从未答应屏蔽三鹿负面
  9. 函数实现不放在头文件的原因,及何时可以放头文件的情况【转】
  10. Hi3519V101_SDK_Vx.x.x.x 目录结构
  11. XmlReader 内部使用NameTable
  12. docker配置 nacos_Docker下Nacos配置应用开发
  13. define macro in xcode project
  14. wps带阴影的边框怎么设置_WPS表格阴影边框如何设置,手把手教你如何设置
  15. 数字资产期权新手入门手册 | TokenInsight
  16. Windows 8激活产品密匙公布
  17. python实现在线答题_仿 StackOverflow 开发在线问答系统
  18. 计算机病毒互助百科,病毒百科——计算机病毒分类
  19. 得到app文稿导出_得到-app分析
  20. Unity3D 通过脚本设置PlayerSettings的属性(GPU Skinning,Auto Graphics APi[OpenGLES2])等

热门文章

  1. 轻巧易用 迅捷PDF转换成Word转换器效果点评
  2. EFS加密文件重装系统无法打开图标带小锁显示绿色解密
  3. handler图片自动切换+listview+GridView+侧滑菜单+fragment
  4. SAP ABAP 标题左边 GOS文件菜单 自定义 CL_GUI_GOS_CONTAINER MENU Gos based menu GOS BUTTON
  5. u3d快速入门图文教程
  6. C++ imagemagick png图片压缩,背景变黑问题
  7. [docker]九、compose是什么?有什么用?以及用compose启动web、redis和wordpress
  8. 饥荒lisp_创建饥荒(Don't starve)专用服务器(Dedicated Server)遇到的问题
  9. 百度旋转验证码识别平台接口文档
  10. php的变量命名规则