The North American Invitational Programming Contest 2016 I.Tourists(LCA求树上任意两点距离+埃式筛法)

The North American Invitational Programming Contest 2016 I.Tourists(LCA求树上任意两点距离+埃式筛法)_第1张图片

The North American Invitational Programming Contest 2016 I.Tourists(LCA求树上任意两点距离+埃式筛法)_第2张图片

The North American Invitational Programming Contest 2016 I.Tourists(LCA求树上任意两点距离+埃式筛法)_第3张图片

The North American Invitational Programming Contest 2016 I.Tourists(LCA求树上任意两点距离+埃式筛法)_第4张图片

思路来源

https://www.cnblogs.com/acjiumeng/p/7249890.html

题意

给定一棵树,求

\sum dis(i,j),1<=i<j<=n,i|j

dis(i,j)定义为树上两点距离+1,n≤2e5

题解

dfs预处理,求根节点到每一点的距离,即点i的深度depth[i]。

这里默认1号点是根节点。

然后在线二分搜索+倍增求LCA,求i和j的最近公共祖先z。

即使树退化成链表,倍增也能logn解决。

i和j的距离就是depth[i]+depth[j]-2*depth[z],

即i到z的距离+j到z的距离。

然后埃氏筛法一波就A了。

代码

  #include
  #include
  #include
  using namespace std;
  typedef long long ll;
  ll cnt,head[200010];
  struct edge{ll to,nex;}e[400010];
  ll parent[200010][30],depth[200010];
  ll ans;
  void init()
  {
	memset(head,-1,sizeof(head));
	cnt=0;
  }
  void add(ll u,ll v)
  {
	e[cnt].to=v;
	e[cnt].nex=head[u];
	head[u]=cnt++;
  } 
 void dfs(ll u,ll pre,ll deep)
 {
   parent[u][0]=pre;
   depth[u]=deep;
   for (int i=head[u];~i;i=e[i].nex)
   {
   	 ll v=e[i].to;
     if(v==pre) continue;
     dfs(v,u,deep+1);
   }
 }
 void double_build(ll n)
 {
   int i,j; 
   for (i=0;i+1<=25;i++)//路径倍增
     for (j=1;j<=n;j++)
       if (parent[j][i]<0) parent[j][i+1]=-1;
       else parent[j][i+1]=parent[parent[j][i]][i];
 }
 ll double_query(ll u,ll v)
 {
   int i;
   if (depth[u]>depth[v]) swap(u,v);
   for (i=0;i<=25;i++)
     if ((depth[v]-depth[u])>>i&1)
       v=parent[v][i];
   if (u==v) return u;
   for (i=25;i>=0;i--) //二进制拆分思想达到倍增
     if (parent[u][i]!=parent[v][i])
     {
       u=parent[u][i];
       v=parent[v][i];
     }
   return parent[u][0];
 }
 int main()
 {
     ll x,y,n;
     scanf("%lld",&n);
     init();
     for(int i=1;i%d=%lld\n",i,j,1+depth[i]+depth[j]-2*(depth[z]));
        } 
     }
     printf("%lld\n",ans);
     return 0;
 }

 

你可能感兴趣的:(The North American Invitational Programming Contest 2016 I.Tourists(LCA求树上任意两点距离+埃式筛法))