zoukankan      html  css  js  c++  java
  • [51nod1709]复杂度分析

      给出一棵n个点的树(以1号点为根),定义dep[i]为点i到根路径上点的个数。众所周知,树上最近公共祖先问题可以用倍增算法解决。现在我们需要算出这个算法精确的复杂度。我们定义计算点i和点j最近公共组先的精确复杂度为bit[dep[i]-dep[lca(i,j)]]+bit[dep[j]-dep[lca(i,j)]](bit[i]表示i在二进制表示下有多少个1,lca(i,j)表示点i和点j的最近公共祖先)。为了计算平均所需的复杂度为多少,请你帮忙计算任意两点计算最近公共组先所需复杂度的总和。
    即计算 sum{ bit[dep[i]-dep[lca(i,j)]]+bit[dep[j]-dep[lca(i,j)]] } ,1<=i<n,i+1<=j<=n;
     Input
      第一行一个数n表示点数(1<=n<=100,000)
      接下来n-1行每行两个数x,y表示一条边(1<=x,y<=n)
     Output
      一个数表示答案

      抱sxt大腿系列。。大概思路就是统计每个点往上跳每一步对答案的贡献。。先倍增预处理出每个点的那些父亲还有到父亲的那条边。

      大概就是统计一下能从子树里跳到当前点的节点数,那些点就能当前父亲其他儿子里能跳到父亲的节点一起贡献。。。

      当然不能每次直接跑。。就把查询都存到到父亲的边里面,最后再dfs一遍统计。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 #include<cstdlib>
     8 #include<bitset>
     9 //#include<ctime>
    10 #define ll long long
    11 #define ull unsigned long long
    12 #define ui unsigned int
    13 #define d double
    14 //#define ld long double
    15 using namespace std;
    16 const int maxn=100233,mxnode=maxn<<1;
    17 struct zs{int too,pre;}e[maxn<<1];int tot,last[maxn];
    18 int fa[maxn][18],fae[maxn][18],num[maxn],pos[maxn],TIM,sz[maxn];
    19 ll sum[maxn],sume[maxn<<1];
    20 int i,j,k,n,m;
    21 ll ans;
    22 
    23 int ra,fh;char rx;
    24 inline int read(){
    25     rx=getchar(),ra=0,fh=1;
    26     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
    27     if(rx=='-')fh=-1,rx=getchar();
    28     while(rx>='0'&&rx<='9')ra=ra*10+rx-48,rx=getchar();return ra*fh;
    29 }
    30 
    31 inline void dfs(int x){
    32     register int i,to;pos[++TIM]=x,sz[x]=num[x]=1;
    33     for(i=1;i<18;i++)fa[x][i]=fa[fa[x][i-1]][i-1],fae[x][i]=fae[fa[x][i-1]][i-1];
    34     for(i=last[x];i;i=e[i].pre)if((to=e[i].too)!=fa[x][0])
    35         fa[to][0]=x,fae[to][0]=i,dfs(to),sz[x]+=sz[to];
    36 }
    37 inline void DFS(int x){
    38     register int i,to;
    39     for(i=last[x];i;i=e[i].pre)if((to=e[i].too)!=fa[x][0])
    40         ans+=1ll*sume[i]*(sz[x]-sz[to]),DFS(to);
    41 }
    42 inline void insert(int a,int b){
    43     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
    44     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
    45 }
    46 int main(){
    47     n=read();register int i,j;
    48     for(i=1;i<n;i++)insert(read(),read());
    49     dfs(1);
    50     int f;
    51     for(j=0;j<18;j++)for(i=1;i<=n;i++)if((f=fa[k=pos[i]][j]))
    52         num[f]+=num[k],sum[f]+=num[k]+sum[k],sume[fae[k][j]]+=num[k]+sum[k];
    53     DFS(1),printf("%lld
    ",ans);
    54 }
    View Code
  • 相关阅读:
    动态调用web服务
    组件设计实战--组件之间的关系 (Event、依赖倒置、Bridge)
    .NET平台下可复用的Tcp通信层实现
    推荐所有的.NET开发人员阅读《J2EE Development without EJB》
    关于跨程序集的反射(续)
    IoC与DI (转载)
    某公司的一道机考题的解答
    使用 EmptyClass 避免条件判断
    EsbAOP应用--权限管理
    企业(分布式)计算十大谬误
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5958356.html
Copyright © 2011-2022 走看看