问题 C: 约会
时间限制: 2 Sec 内存限制: 256 MB题目描述

输入

输出
样例输入
4
1 2
1 3
2 4
1
2 3
样例输出
1
提示
T掉的树剖
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#define V 100009
#define LL long long
using namespace std;
int n,a[V],f[V];
struct da
{
int to,next;
}Edge[V*2];
deque<int>Q[2];
int head[V],tot,siz[V],son[V],dep[V],top[V],id[V],cnt,ps[V];
inline void add(int x,int y)
{
Edge[tot].to=y;
Edge[tot].next=head[x];
head[x]=tot++;
}
inline void dfs1(int x)
{
int v;
siz[x]=1;
for(int i=head[x];i!=-1;i=Edge[i].next)
{
v=Edge[i].to;
if(v!=f[x])
{
f[v]=x;
dep[v]=dep[x]+1;
dfs1(v);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]])
son[x]=v;
}
}
}
inline void dfs2(int x,int ss)
{
int v;
id[x]=++cnt;
ps[cnt]=x;
top[x]=ss;
if(son[x])dfs2(son[x],ss);
for(int i=head[x];i!=-1;i=Edge[i].next)
{
v=Edge[i].to;
if(v!=f[x]&&v!=son[x])
dfs2(v,v);
}
}
inline int mdx(int sbb,int mdd,int x,int y,int num)
{
if((sbb-mdd)%2!=0)return 0;
int xx,yy;
xx=(sbb-mdd)/2;
y=Q[0].front();Q[0].pop_front();
while(dep[y]-dep[x]<xx)
{
xx-=(dep[y]-dep[x]);
x=y;
y=Q[0].front();
}
xx=id[x]+xx;
xx=ps[xx];
return siz[xx]-siz[son[xx]];
}
inline int mdy(int sbb,int mdd,int x,int y,int num)
{
if((mdd-sbb)%2!=0)return 0;
int xx,yy;
xx=(sbb-mdd)/2;
y=Q[1].front();Q[1].pop_front();
while(dep[y]-dep[x]<xx)
{
xx-=(dep[y]-dep[x]);
x=y;
y=Q[1].front();
}
xx=id[x]+xx;
xx=ps[xx];
return siz[xx]-siz[son[x]];
}
inline int QQ(int x,int y)
{
int fx=top[x],fy=top[y];
int num=0;
Q[0].push_front(x);
Q[1].push_front(y);
int sbb=dep[x],mdd=dep[y],mb;
while(fx!=fy)
{
if(dep[fx]<dep[fy])
{
num^=1;
swap(x,y);
swap(fx,fy);
}
x=f[x];
Q[num].push_front(x);
fx=top[x];
}
if(dep[x]>dep[y])
{
num^=1;
swap(x,y);
}
Q[num].pop_front();
sbb=sbb-dep[x];
mdd=mdd-dep[x];
if(sbb==mdd)
return siz[x]-siz[son[x]]-siz[top[Q[num].front()]]+dep[x]-1;
else if(sbb>mdd)
return mdx(sbb,mdd,x,y,num);
else
return mdy(sbb,mdd,x,y,num);
}
inline int read()
{
int mdd=0,sbb=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
sbb=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
mdd=mdd*10+ch-'0';
ch=getchar();
}
return mdd*sbb;
}
int main()
{
//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);
//freopen("bcatch.in","r",stdin);freopen("bcatch.out","w",stdout);
memset(head,-1,sizeof(head));
//n=read();
scanf("%d",&n);
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dep[1]=1;
dfs1(1);
dfs2(1,1);
int m;
m=read();
while(m--)
{
scanf("%d%d",&x,&y);
//x=read();
// y=read();
printf("%d\n",QQ(x,y));
//cout<<QQ(x,y)<<endl;
Q[0].clear();
Q[1].clear();
}
}
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#define V 100009
#define LL long long
using namespace std;
int n,a[V],f[V];
struct da
{
int to,next;
}Edge[V*2];
deque<int>Q[2];
int head[V],tot,siz[V],dep[V],d[V][30];
inline void add(int x,int y)
{
Edge[tot].to=y;
Edge[tot].next=head[x];
head[x]=tot++;
}
inline void dfs1(int x)
{
int v;
siz[x]=1;
for(int i=head[x];i!=-1;i=Edge[i].next)
{
v=Edge[i].to;
if(v!=f[x])
{
f[v]=x;
dep[v]=dep[x]+1;
dfs1(v);
siz[x]+=siz[v];
}
}
}
inline void RMQ()
{
for(int i=1;i<=n;i++)d[i][0]=f[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
if(d[i][j-1])
d[i][j]=d[d[i][j-1]][j-1];
}
inline int lca(int x,int y)
{
int i,j;
if(dep[x]<dep[y])swap(x,y);
for(i=0;(1<<i)<=dep[x];i++);
i--;
for(j=i;j>=0;j--)
if(dep[x]-(1<<j)>=dep[y])
x=d[x][j];
if(x==y)return x;
//cout<<dep[x]<<" "<<dep[y]<<endl;
for(j=i;j>=0;j--)
{
if(d[x][j]&&d[x][j]!=d[y][j])
{
x=d[x][j];
y=d[y][j];
}
}
//cout<<x<<" "<<y<<endl;
return f[x];
}
int QQ(int x,int y)
{
int i,j;
int z=lca(x,y);
int xx=dep[x],yy=dep[y],zz=dep[z];
if((xx-zz+yy-zz)%2!=0)return 0;
if(x==y)return n;
if(xx==yy)
{
for(i=0;(1<<i)<=xx;i++);
i--;
for(j=i;j>=0;j--)
if(dep[x]-(1<<j)>=zz+1)
x=d[x][j];
for(i=0;(1<<i)<=yy;i++);
i--;
for(j=i;j>=0;j--)
if(dep[y]-(1<<j)>=zz+1)
y=d[y][j];
//cout<<x<<" #$% "<<y<<" "<<z<<endl;
return n-siz[x]-siz[y];
}
if(dep[x]<dep[y])swap(x,y);
int ww=(xx+yy-2*zz)/2;
ww=dep[x]-ww;
for(i=0;(1<<i)<=dep[x];i++);
i--;
for(j=i;j>=0;j--)
if(dep[x]-(1<<j)>=ww+1)
x=d[x][j];
// cout<<" $%^ !!"<<siz[f[x]]<<" "<<siz[x]<<" "<<f[x]<<" "<<x<<endl;
return siz[f[x]]-siz[x];
}
int main()
{
//freopen("in.txt","r",stdin);freopen("22.txt","w",stdout);
//freopen("bcatch.in","r",stdin);freopen("bcatch.out","w",stdout);
memset(head,-1,sizeof(head));
//n=read();
scanf("%d",&n);
int x,y;
for(int i=1;i<n;i++)
{
//x=read();
//y=read();
scanf("%d%d",&x,&y);
//if(x*y==12)
//cout<<x<<" @@ "<<y<<endl<<endl;
add(x,y);
add(y,x);
}
dep[1]=1;
dfs1(1);
RMQ();
int m;
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&x,&y);
printf("%d\n",QQ(x,y));
}
}