zoukankan      html  css  js  c++  java
  • CF588 DIV2 E Kamil and Making a Stream 树上倍增

    CF588-DIV2-E Kamil and Making a Stream

    http://codeforces.com/contest/1230/problem/E

    被打的晕头转向,这大概就是菜吧。。

    题意

    一个有根树,求所有 <父亲,儿子> 链的gcd的和。

    思路

    看起来可以o(n)做(不过不会),但是我们知道gcd收敛很快,最差收敛一次也是二分之一,那我们我们树上倍增暴力一下每个儿子到根的gcd情况,最多有log种不同的答案,每次不同答案之间的跳跃的时间是log(其实复杂度很爆炸的),众所周知CF测评机很快,所以通过了该题。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    #define X first
    #define Y second
    #define PB push_back
    #define LL long long
    #define pii pair<int,int>
    #define MEM(x,y) memset(x,y,sizeof(x))
    #define bug(x) cout<<"debug "#x" is "<<x<<endl;
    #define FIO ios::sync_with_stdio(false);
    #define ALL(x) x.begin(),x.end()
    typedef long long ll;
    const ll mod = 1e9+7;
    const int maxn =1e5+10;
    LL a[maxn];
    LL ans=0;
    LL dp[maxn][21],fa[maxn][21];
    LL add(LL a,LL b){return (a+b)%mod;};
    LL mul(LL a,LL b){return (a*b)%mod;};
    vector<int> V[maxn];
    void dfs(int x,int f){
        fa[x][0]=x;fa[x][1]=f;
        dp[x][0]=a[x];dp[x][1]=__gcd(a[x],a[f]);
        for(int c:V[x])
            if(c!=f) dfs(c,x);
    }
    void gao(int x,LL g){
        LL ret=0;
        int flag=0;
        if(x==1) return;
        for(int i=20;i>=1;i--){
            if(fa[x][i]!=0&&__gcd(g,dp[x][i])==g){
                ans=add(ans,mul(g,1<<(i-1)));
                gao(fa[x][i],g);
                flag=1;
                break;
            }
        }
        if(!flag) ans=add(ans,__gcd(g,dp[x][1])),gao(fa[x][1],__gcd(g,dp[x][1]));
        return;
    }
    int main(){
        FIO;
        int n,x,y;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<n;i++){
            cin>>x>>y;
            V[x].PB(y),V[y].PB(x);
        }
        a[0]=mod;
        dfs(1,0);
        for(int i=2;i<=20;i++)
            for(int j=1;j<=n;j++)
                fa[j][i]=fa[fa[j][i-1]][i-1],dp[j][i]=__gcd(dp[j][i-1],dp[fa[j][i-1]][i-1]);
        for(int i=1;i<=n;i++)
            ans=add(ans,a[i]),gao(i,a[i]);
        cout<<ans<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    [adminitrative][archlinux][setfont] 设置console的字体大小
    [daily][archlinux][rsync] rsync
    [skill][msgpack] 初试msgpack库以及基本使用
    AWS之搭建深度学习主机
    AWS之SSH登录:使用 PuTTY 从 Windows 连接到 Linux 实例
    加拿大大学排名 by USNews
    Python多进程vs多线程
    Python之JSON使用
    Python之模块与包
    Android重打包+重新签名工具Apktool Box
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/11577927.html
Copyright © 2011-2022 走看看