## ZigZagK的博客

Never give up fighting!

# 【LCT】BZOJ2002(Hnoi2010)[Bounce 弹飞绵羊]题解

## 示例程序

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=200000;

int n,te,K[maxn+5];
struct LCT
{
int father[maxn+5],son[maxn+5][2],si[maxn+5];
bool flip[maxn+5];
void Pushup(int p) {si[p]=si[son[p][0]]+1+si[son[p][1]];}
void Pushdown(int p)
{
if (!flip[p]) return;
flip[p]=false;
}
bool is_ro(int p) {return p!=son[father[p]][0]&&p!=son[father[p]][1];}
void Rotate(int p)
{
int fa=father[p],d=p==son[fa][0];
if (!is_ro(fa)) son[father[fa]][fa==son[father[fa]][1]]=p;
son[fa][d^1]=son[p][d];father[son[p][d]]=fa;son[p][d]=fa;
Pushup(fa);Pushup(p);father[p]=father[fa];father[fa]=p;
}
int top,stk[maxn+5];
void Splay(int p) //用非递归Splay比较方便，省去了找p的过程
{
stk[++top]=p;
for (int i=p;!is_ro(i);i=father[i]) stk[++top]=father[i];
while (top) Pushdown(stk[top--]); //因为非递归，所以要先将上面的点传标记
while (!is_ro(p))
{
int fa=father[p];
if (!is_ro(fa))
{
int d1=fa==son[father[fa]][1],d2=p==son[fa][1];
if (d1==d2) Rotate(fa); else Rotate(p);
}
Rotate(p);
}
}
void Access(int p)
{
int lst=0;
while (p)
{
Splay(p);son[p][1]=lst;Pushup(p);
lst=p;p=father[p];
}
}
void Cut(int x,int y)
{
make_ro(y);Access(x);Splay(x);
father[y]=son[x][0]=0;Pushup(x);
}
};
LCT tr;

bool Eoln(char ch) {return ch==10||ch==13||ch==EOF;}
{
int tot=0,f=1;char ch=getchar(),lst='+';
while ('9'<ch||ch<'0') {if (ch==EOF) return EOF;lst=ch;ch=getchar();}
if (lst=='-') f=-f;
while ('0'<=ch&&ch<='9') tot=tot*10+ch-48,ch=getchar();
x=tot*f;
return Eoln(ch);
}
void First_init() {for (int i=1;i<=n+1;i++) tr.si[i]=1;}
int main()
{
freopen("program.in","r",stdin);
freopen("program.out","w",stdout);
while (te--)
{
if (td==1)
{
tr.make_ro(n+1);tr.Access(x);tr.Splay(x);
printf("%d\n",tr.si[x]-1);
} else
//和原来的目的地断开，连接到新的目的地上
}
return 0;
}

08-10 1693

08-18 815

10-21 2015

01-22 472

06-22 543

07-20 434

08-13 334

07-18 316

08-03 661

11-24 140