题目连接
题意
题解
- 注意
s
p
l
i
t
split
split后找父亲的时候一定要
p
u
s
h
_
d
o
w
n
push\_down
push_down就行了
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
#define inf 0x3f3f3f3f
namespace LCT{
int ch[maxn][2],fa[maxn],mark[maxn];
int val[maxn],siz[maxn];
inline bool not_root(int x) {return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
inline int dir(int x) {return ch[fa[x]][1]==x;}
inline void add_mark(int x) {swap(ch[x][0],ch[x][1]);mark[x]^=1;}
inline void push_down(int x) {
if(mark[x]) {
if(ch[x][0]) add_mark(ch[x][0]);
if(ch[x][1]) add_mark(ch[x][1]);
mark[x]=0;
}
}
inline void push_up(int x) {
siz[x]=1;
if(ch[x][0]) siz[x]+=siz[ch[x][0]];
if(ch[x][1]) siz[x]+=siz[ch[x][1]];
}
inline void pushall(int x) {
if(not_root(x)) pushall(fa[x]);
push_down(x);
}
inline void rotate(int x){
int y=fa[x],z=fa[y],k=dir(x);
if(ch[x][k^1]) fa[ch[x][k^1]]=y;ch[y][k]=ch[x][k^1];
if(not_root(y)) ch[z][dir(y)]=x;fa[x]=z;
ch[x][k^1]=y;fa[y]=x;
push_up(y);
}
inline void splay(int x,int goal=0) {
pushall(x);
while(not_root(x)) {
int y=fa[x],z=fa[y];
if(not_root(y)) {
if(dir(x)==dir(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
push_up(x);
}
inline void access(int x) {
for(int y=0;x;y=x,x=fa[x]) {
splay(x);ch[x][1]=y;push_up(x);
}
}
inline void make_root(int x) {
access(x);splay(x);add_mark(x);
}
inline int find_root(int x) {
access(x);splay(x);
while(ch[x][0]) push_down(x),x=ch[x][0];
splay(x);
return x;
}
inline void split(int x,int y) {
make_root(x);access(y);splay(y);
}
inline bool link(int x,int y) {
make_root(x);
if(find_root(y)==x) return 0;
fa[x]=y;return 1;
}
inline bool cut(int x,int y) {
make_root(x);
if(find_root(y)!=x||fa[y]!=x||ch[y][0]) return 0;
fa[y]=ch[x][1]=0;
push_up(x);
return 1;
}
};
using namespace LCT;
int n,m,opt,a[maxn],x,y;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
if(i+a[i]<=n) link(i,i+a[i]);
else link(i,n+1);
}
for(int i=1;i<=m;i++) {
scanf("%d",&opt);
if(opt==1) {
scanf("%d",&x);
split(x,n+1);
int k=ch[n+1][0];
while(ch[k][1]) push_down(k),k=ch[k][1];
printf("%d %d\n",k,siz[n+1]-1);
}else {
scanf("%d %d",&x,&y);
if(x+a[x]<=n) cut(x+a[x],x);
else cut(n+1,x);
a[x]=y;
if(x+a[x]<=n) link(x+a[x],x);
else link(n+1,x);
}
}
}