比赛时间:2018.10.18 选手:lrllrl 得分:100+90+20=210 用时:2小时
裸的LCA,随你怎么求,白送的分。
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int s=0,f=0;char ch=getchar();
while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
if(f)s=-s;return s;
}
const int N=4e4+10;
int n,m,root,hd[N],tot,f[N][20],dep[N];
struct Edge{
int v,nx;
}e[N<<1];
inline void add(int u,int v)
{
e[++tot].v=v;
e[tot].nx=hd[u];
hd[u]=tot;
}
void dfs1(int u,int fa)
{
for(int i=hd[u];i;i=e[i].nx)
{
int v=e[i].v;
if(v==fa)continue;
dep[v]=dep[u]+1;
dfs1(v,u);
}
}
void dfs2(int u,int fa)
{
for(int i=hd[u];i;i=e[i].nx)
{
int v=e[i].v;
if(v==fa)continue;
f[v][0]=u;
for(int i=1;(1<<i)<=dep[v];i++)
f[v][i]=f[f[v][i-1]][i-1];
dfs2(v,u);
}
}
int lca(int u,int v)
{
if(dep[u]>dep[v])swap(u,v);
int d=dep[v]-dep[u];
for(int i=0;d;d>>=1,i++)
if(d&1)v=f[v][i];
if(u==v)return u;
for(int i=19;i>=0;i--)
if(f[v][i]!=f[u][i])v=f[v][i],u=f[u][i];
return f[u][0];
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
n=read();
int u,v;
for(int i=1;i<=n;i++)
{
u=read();v=read();
if(v==-1)root=u;
else add(u,v),add(v,u);
}
dep[root]=1;dfs1(root,0);dfs2(root,0);
m=read();
for(int i=1;i<=m;i++)
{
u=read();v=read();
int fa=lca(u,v);
if(u==fa)puts("1");
else if(v==fa)puts("2");
else puts("0");
}
return 0;
}
推个公式化简就好。
a n s = 1 n × ∑ i = 1 n ∑ j = 1 n ± ( a i − b j ) 2 ans=\frac{1}{n}\times\sum_{i=1}^n\sum_{j=1}^n\pm(a_i-b_j)^2 ans=