HDU-5967 小R与手机(LCT)
来源:互联网 发布:短域名生成算法 编辑:程序博客网 时间:2024/04/30 07:34
小R与手机
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 456 Accepted Submission(s): 108
Problem Description
小R有n部手机,为了便于管理,他对一些手机设置了“呼叫转移”的功能。
具体来说,第i ( 1 <= i <= n )部手机有个参数ai(0<=ai<=n,ai≠ i )。若 ai ≠ 0 则表示第i部手机接到电话时会将电话无条件转移给第 ai 部手机(此时如果 aai≠0 , 会继续进行呼叫转移)。
如果一部手机接到电话会导致至少109 次呼叫转移,则这次电话无法接通。
现在有m个事件依次发生,具体如下:
∙ 1 x y表示将第x部手机的参数设置为y,即将 ax 设置为y ;
∙ 2 x表示询问给第x部手机打电话,最终接到电话的手机编号(如果无法接通, 则编号为-1 )。
小R当然知道怎么做啦!但是他想考考你。
具体来说,第i ( 1 <= i <= n )部手机有个参数
如果一部手机接到电话会导致至少
现在有m个事件依次发生,具体如下:
小R当然知道怎么做啦!但是他想考考你。
Input
只包含一组测试数据。
输入的第一行有两个整数n, m。保证1 <= n, m <= 2 *105 。
接下来一行,包含n个整数,第i个整数为ai 。
接下来m行,每一行为一个事件,具体格式见问题描述。
对于事件1,保证1 <= x <= n, 0 <= y <= n, x≠ y ;对于事件2,保证1 <= x <= n
输入的第一行有两个整数n, m。保证1 <= n, m <= 2 *
接下来一行,包含n个整数,第i个整数为
接下来m行,每一行为一个事件,具体格式见问题描述。
对于事件1,保证1 <= x <= n, 0 <= y <= n, x
Output
对每个询问事件输出一行一个整数,表示最终接到电话的手机编号,如果无法接 通,输出-1。
Sample Input
5 62 3 4 5 02 22 51 4 32 11 4 02 1
Sample Output
55-14
LCT,如果某次加边时会构成环,那么这条边的两端一定是根节点和其子树节点,每次加边的时候判断一下是否会构成环,会的话就保存好那条边,还要判断本来是否有环,有环的话要把环拆开并把保存好的边加入Splay-tree中
#include<bits/stdc++.h>#define rson m+1,r,rt<<1|1#define lson l,m,rt<<1#define FIN freopen("input.txt","r",stdin);using namespace std;typedef unsigned long long ULL;typedef long long LL;const int MX = 2e5 + 5;typedef pair<int, int> PII;int n, m, a[MX];int ch[MX][2], pre[MX], clr[MX];bool root[MX];void init() { for (int i = 0; i <= n; i++) { ch[i][0] = ch[i][1] = clr[i] = 0; pre[i] = 0; root[i] = 1; }}void Rotate(int x) { int y = pre[x], kind = ch[y][1] == x; ch[y][kind] = ch[x][!kind]; pre[ch[y][kind]] = y; pre[x] = pre[y]; pre[y] = x; ch[x][!kind] = y; if (root[y]) root[y] = 0, root[x] = 1; else ch[pre[x]][ch[pre[x]][1] == y] = x;}int t;void Splay(int x) { while (!root[x]) { int f = pre[x], ff = pre[f]; if (!root[f]) { if ((ch[ff][1] == f) == (ch[f][1] == x)) Rotate(f); else Rotate(x); } Rotate(x); }}int Access(int x) { int y = 0; t = x; while (x) { Splay(x); root[ch[x][1]] = 1; //在辅助树中切除右子树(曾经的偏爱子节点) root[ch[x][1] = y] = 0; x = pre[y = x]; } return y;}int findroot(int x) { Access(x); Splay(x); while (ch[x][0]) x = ch[x][0]; Splay(x); return x;}void cut(int v) { Access(v); Splay(v); pre[ch[v][0]] = pre[v]; pre[v] = 0; root[ch[v][0]] = 1; ch[v][0] = 0;}void link(int u, int v) { Access(v); Splay(v); pre[v] = u;}void Link(int u, int v) { int rt = findroot(v); if (rt == v) clr[rt] = 0; else cut(v); if (clr[rt] && findroot(clr[rt]) != rt) { link(clr[rt], rt); clr[rt] = 0; } if(u==0) return; if (findroot(u) == v) clr[v] = u; else link(u, v);}int main() { //freopen("in.txt", "r", stdin); while (~scanf("%d%d", &n, &m)) { init(); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) if (a[i]) Link(a[i], i); for (int i = 1; i <= m; i++) { int op, x, y; scanf("%d", &op); if (op == 1) { scanf("%d%d", &x, &y); Link(y, x); } else { scanf("%d", &x); x = findroot(x); printf("%d\n", clr[x] ? -1 : x); } } } return 0;}
阅读全文
0 0
- HDU-5967 小R与手机(LCT)
- HDU 5967 小R与手机 (LCT)
- Hdu 5967 小R与手机
- 小R与手机
- HDU 5967 小R与手机(Link Cut Tree 基环树森林)
- HDU 5967 小R与手机 CDQ分治+回滚并查集
- R语言,来模拟LCT
- hdu 5002 Tree (LCT)
- hdu 3966 LCT
- hdu 5052 (LCT)
- HDU 4010 LCT
- HDU 5052 LCT
- hdu 4010 LCT
- hdu 2475 box LCT
- hdu 4010 LCT
- hdu 5002 Tree (LCT)
- hdu 5002 (LCT模板)
- hdu 4010 (LCT模板)
- Ansible管理windows系统
- GC 小结
- 微信提现(1)---企业现金红包方式
- 三条命令 搭建 shadowsock 服务器
- 字符串类型转换
- HDU-5967 小R与手机(LCT)
- 常见android手机分辨率
- 读写锁
- omnetpp下学习AODV的记录
- 如何在win10系统中使用vc6.0
- Java关键字及其作用
- maven本地仓库配置
- 【jzoj5246】【NOIP2017模拟8.8A组】【Trip】【笛卡尔树】【tarjan-lca】
- BGAQRCode-Android