您的位置:首页 > 其它

Codeforces Round #294 (Div. 2) 题解

2015-05-12 23:53 471 查看
A题:

给出一个8*8的棋盘,棋盘上是一些字符,大写字母代表white的分数,小写代表black的分数,问最后谁的分数多,直接扫一遍就好了。

#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

const int maxn=100000+5;

int siz[maxn];
int dep[maxn];
int p[maxn][20];

struct Edge
{
int to,next;
}edge[maxn<<1];

int head[maxn];
int tot;

void init(int n)
{
memset(head,-1,sizeof(head));
tot=0;
memset(dep,0,sizeof(dep));

for(int i=1;i<=n;i++)
for(int j=0;j<20;j++)
p[i][j]=-1;
}

void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}

void dfs(int n,int rt)
{
siz[rt]=1;
for(int i=head[rt];~i;i=edge[i].next)
{
int v=edge[i].to;
if(!dep[v])
{
dep[v]=dep[rt]+1;
p[v][0]=rt;
dfs(n,v);
siz[rt]+=siz[v];
}
}
}

void init_lca(int n)
{
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i<=n;i++)
{
if(p[i][j-1]!=-1)
{
p[i][j]=p[p[i][j-1]][j-1];
}
}
}
}

int solve(int n,int a,int b)
{
if(a==b)
return n;

if(dep[a]<dep[b])
swap(a,b);

int cnt;
for(cnt=0;(1<<cnt)<=dep[a];cnt++)
;
cnt--;

//printf("cnt=%d\n",cnt);

int init_a=a;

for(int j=cnt;j>=0;j--)
{
if(dep[a]-(1<<j)>=dep[b])
a=p[a][j];
}

//printf("a=%d\n",a);

if(init_a==a)
{
for(int j=cnt;j>=0;j--)
{
if(p[a][j]!=-1&&p[a][j]!=p[b][j])
{
a=p[a][j];
b=p[b][j];
}
}
return (n-siz[a]-siz[b]);
}
else if(a==b)
{
if((dep[init_a]-dep[a])%2)
return 0;

int mid=init_a;
int temp=(dep[init_a]-dep[a])/2;
temp=dep[init_a]-temp+1;
for(int j=cnt;j>=0;j--)
if(dep[mid]-(1<<j)>=temp)
mid=p[mid][j];
int ans=siz[p[mid][0]]-siz[mid];
return ans;
}
else
{
int init_b=b;
for(int j=cnt;j>=0;j--)
{
if(p[a][j]!=-1&&p[a][j]!=p[b][j])
{
a=p[a][j];
b=p[b][j];
}
}
int lca=p[a][0];
int cur=dep[init_a]+dep[init_b]-2*dep[lca];
if(cur%2)
return 0;
int mid=init_a;
cur/=2;
cur=dep[init_a]-cur+1;
for(int j=cnt;j>=0;j--)
if(dep[mid]-(1<<j)>=cur)
mid=p[mid][j];
int ans=siz[p[mid][0]]-siz[mid];
return ans;
}
}

int main()
{
int n;

while(scanf("%d",&n)!=EOF)
{
init(n);

for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
dep[1]=1;
dfs(n,1);

init_lca(n);

int m;
scanf("%d",&m);

/*
for(int i=1;i<=n;i++)
printf("%d\n",dep[i]);
*/

for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",solve(n,a,b));
}

}

return 0;
}


109ms
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: