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

    题解:

    注意到,如果第j位有贡献,那么从i往上跳2^j,然后不能再跳超过2^j。 
    因此可以考虑倍增。 

    代码:

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=100233,M=N<<1;
    struct zs{int too,pre;}e[N<<1];
    int tot,last[N],fa[N][18],fae[N][18],num[N],pos[N],TIM,sz[N];
    ll sum[N],sume[maxn<<1],ans;
    int k,n,m,ra,fh;
    char rx;
    inline int read()
    {
        rx=getchar(),ra=0,fh=1;
        while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
        if(rx=='-')fh=-1,rx=getchar();
        while(rx>='0'&&rx<='9')
         ra=ra*10+rx-48,rx=getchar();return ra*fh;
    }
    void dfs(int x)
    {
        int to;
        pos[++TIM]=x;sz[x]=num[x]=1;
        for(int 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];
        for(int i=last[x];i;i=e[i].pre)
         if((to=e[i].too)!=fa[x][0])
          fa[to][0]=x,fae[to][0]=i,dfs(to),sz[x]+=sz[to];
    }
    inline void DFS(int x)
    {
        register int i,to;
        for(i=last[x];i;i=e[i].pre)if((to=e[i].too)!=fa[x][0])
            ans+=1ll*sume[i]*(sz[x]-sz[to]),DFS(to);
    }
    void insert(int a,int b)
    {
        e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
        e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
    }
    int main()
    {
        n=read();
        for(int i=1;i<n;i++)insert(read(),read());
        dfs(1);
        int f;
        for(int j=0;j<18;j++)
         for(int i=1;i<=n;i++)
          if((f=fa[k=pos[i]][j]))
           num[f]+=num[k],sum[f]+=num[k]+sum[k],
           sume[fae[k][j]]+=num[k]+sum[k];
        DFS(1),printf("%lld
    ",ans);
    }
  • 相关阅读:
    【Linux】grep or
    win10查看WiFi密码
    【WPF】Border有显示模糊的情况
    【Spark】配置项spark.network.timeout 的单位是什么
    【Linux】free命令中 free与 available 的区别
    Spark2.3配置项
    java获取jar包执行路径
    编译 thrift-0.14.2 的 C++ 版本
    拉端保障方案
    编译运行ebpf代码的流水账
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7506684.html
Copyright © 2011-2022 走看看