CF1230 E. Kamil and Making a Stream gcd+暴力

比赛的时候TLE,第二天发现合并方向合并错了~

改了一下顺序就切了~

又掉分了,好难过QAQ......

Code: 

#include <bits/stdc++.h>
#define N 100005 
#define mod 1000000007
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
struct Node 
{
    ll gc,tmp;
    Node(ll gc=0,ll tmp=0):gc(gc),tmp(tmp){}  
};   
bool cmp(Node a,Node b) 
{
    return a.gc < b.gc;    
}
vector<Node>G[N];              
vector<Node>A;    
int n,edges; 
ll val[N], ans=0;    
int hd[N],to[N<<1],nex[N<<1];  
void add(int u,int v) 
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
}
void dfs(int u,int ff) 
{    
    if(ff!=0) 
    {
        A.clear();     
        for(int j=0;j<G[ff].size();++j) A.push_back(G[ff][j]);                 
        for(int i=0;i<A.size();++i) A[i].gc=__gcd(A[i].gc, val[u]);  
    }   
    A.push_back(Node(val[u], 1));    
    sort(A.begin(), A.end(), cmp);     
    int i,j; 
    for(i=0;i<A.size();i=j) 
    {   
        for(j=i;j<A.size() && A[j].gc==A[i].gc;) 
        {
            ++j;  
        }
        ll pp=0; 
        for(int k=i;k<j;++k) 
        {
            pp+=A[k].tmp;    
        }
        G[u].push_back(Node(A[i].gc, pp));    
    }
    sort(G[u].begin(), G[u].end(), cmp);    
    for(i=0;i<G[u].size();++i)         
        ans=(ans+G[u][i].gc*G[u][i].tmp%mod)%mod;    
    for(int i=hd[u];i;i=nex[i]) 
    {    
        int v=to[i];      
        if(v==ff) continue;   
        dfs(v, u);     
    }   
}
int main() 
{ 
    int i,j; 
    // setIO("input"); 
    scanf("%d",&n); 
    for(i=1;i<=n;++i) scanf("%lld",&val[i]);     
    for(i=1;i<n;++i) 
    {
        int a,b; 
        scanf("%d%d",&a,&b), add(a,b),add(b,a);  
    }
    dfs(1,0); 
    printf("%lld\n",ans);     
    return 0; 
}

  

posted @ 2019-09-24 18:25  EM-LGH  阅读(414)  评论(0编辑  收藏  举报