牛客挑战赛40E 小V和gcd树(边权为俩点的gcd,求路径上小于等于k的边权数)

题:https://ac.nowcoder.com/acm/contest/5555/E

分析:树上路径,带修改,考虑树链剖分,对于操作1,把u的值改为x,影响的权值只是,u的父亲以及他孩子之间的边,那么我们就把重链的部分修改,其他的边不修改,即对u--son[u]和u--fa[u]的边的gcd修改即可(注意后者要保证在当前重链上才可修改);对于操作2,借助tp往上跳的过程中,由于重链上的边我们处理过了,所以这部分直接加,另外就是重链以为的部分边,这些边只可能是u--fa[u]之间的边,所以暴力统计即可

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define pb push_back
const int M=2e4+4;
int fa[M],sz[M],deep[M],ans[M],dfn[M],tp[M],son[M],a[M];
int cnt;
vector<int>g[M];
void dfs1(int u,int f){
    fa[u]=f,sz[u]=1,deep[u]=deep[f]+1;
    for(auto v:g[u]){
        if(v!=f){
            dfs1(v,u);
            sz[u]+=sz[v];
            if(sz[son[u]]<sz[v])
                son[u]=v;
        }
    }
}
void dfs2(int u,int top){
    tp[u]=top;
    dfn[u]=++cnt;
    if(u!=top)
        ans[dfn[u]]=__gcd(a[u],a[fa[u]]);
    if(son[u])
        dfs2(son[u],top);
    for(auto v:g[u]){
        if(v!=fa[u]&&v!=son[u])
            dfs2(v,v);
    }
}
int solve(int u,int v,int k){
    int res=0;
    while(tp[u]!=tp[v]){
        if(deep[tp[u]]<deep[tp[v]])
            swap(u,v);
        for(int i=dfn[tp[u]]+1;i<=dfn[u];i++)
            res+=(ans[i]<=k);
        res+=(__gcd(a[tp[u]],a[fa[tp[u]]])<=k);
        u=fa[tp[u]];
    }
    if(deep[u]<deep[v])
        swap(u,v);
    for(int i=dfn[v]+1;i<=dfn[u];i++)
        res+=(ans[i]<=k);
    return res;
}
int main(){
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int u,v,i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        g[u].pb(v),g[v].pb(u);
    }
    dfs1(1,0),dfs2(1,1);
    while(q--){
        int op,u,v,x,k;
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d",&u,&x);
            a[u]=x;
            if(tp[u]!=u)
                ans[dfn[u]]=__gcd(a[u],a[fa[u]]);
            if(son[u])
                ans[dfn[son[u]]]=__gcd(a[u],a[son[u]]);
        }
        else{
            scanf("%d%d%d",&u,&v,&k);
            printf("%d\n",solve(u,v,k));
        }
    }
    return 0;
}
View Code

 

posted @ 2020-05-19 22:00  starve_to_death  阅读(213)  评论(0编辑  收藏  举报