您的位置:首页 > 其它

【TJOI & HEOI 2016】【JZOJ 4604】【BZOJ 4551】 树

2016-07-11 16:54 447 查看

Description



100%1≤N,Q≤100000100\%1\leq N,Q\leq 100000

Analysis

一秒无脑链剖,能过。

离线,把操作反过来做是正解。

Code

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define efo(i,v) for(int i=last[v];i;i=next[i])
using namespace std;
const int N=100010,M=N*2;
int n,m,tot,pos,to[M],next[M],last
,fa
,size
,w
,p
,son
,top
;
bool a[N*4];
void link(int u,int v)
{
to[++tot]=v,next[tot]=last[u],last[u]=tot;
}
void dfs1(int v,int from)
{
int k=0;
size[v]=1,fa[v]=from;
efo(i,v)
{
int u=to[i];
if(u==from) continue;
dfs1(u,v);
if(size[u]>size[k]) k=u;
size[v]+=size[u];
}
son[v]=k;
}
void dfs2(int v,int from,int t)
{
w[v]=++m,p[m]=v,top[v]=t;
if(son[v]) dfs2(son[v],v,t);
efo(i,v)
{
int u=to[i];
if(u==from || u==son[v]) continue;
dfs2(u,v,u);
}
}
void find(int v,int l,int r)
{
if(!a[v]) return;
if(l==r)
{
pos=p[l];
return;
}
int mid=(l+r)>>1;
if(a[v+v+1]) find(v+v+1,mid+1,r);
else
if(a[v+v]) find(v+v,l,mid);
}
void serch(int v,int l,int r,int x,int y)
{
if(!a[v]) return;
if(l==x && r==y)
{
find(v,l,r);
return;
}
int mid=(l+r)>>1;
if(y<=mid) serch(v+v,l,mid,x,y);
else
if(x>mid) serch(v+v+1,mid+1,r,x,y);
else
serch(v+v,l,mid,x,mid),serch(v+v+1,mid+1,r,mid+1,y);
}
int query(int v)
{
while(v)
{
pos=0;
serch(1,1,n,w[top[v]],w[v]);
if(pos) return pos;
v=fa[top[v]];
}
}
void modify(int v,int l,int r,int x)
{
if(l==r)
{
a[v]=1;
return;
}
int mid=(l+r)>>1;
if(x<=mid) modify(v+v,l,mid,x);
else modify(v+v+1,mid+1,r,x);
a[v]=a[v+v] || a[v+v+1];
}
int main()
{
int _,u,v;
scanf("%d %d",&n,&_);
fo(i,1,n-1)
{
scanf("%d %d\n",&u,&v);
link(u,v),link(v,u);
}
dfs1(1,0);
dfs2(1,0,1);
modify(1,1,n,1);
char ch;
while(_--)
{
scanf("%c %d\n",&ch,&v);
if(ch=='Q') printf("%d\n",query(v));
else modify(1,1,n,w[v]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: