zoukankan      html  css  js  c++  java
  • Codechef DGCD Dynamic GCD(D12 树上GCD)

    题意

    给一棵树,点有点权,有两种操作:询问路径点权gcd,将路径点权+val;

    1 <= N <= 50000
    1 <= Q <= 50000
    0 <= u, v <= N-1 
    1 <= vi <= 104 //初始点权
    0 <= d <= 104 //增加点权

    题解

    先树链剖分,就和序列的gcd求法差不多,记得询问取abs

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=50005;
    int n,m;
    int a[maxn],aa[maxn];
    int head[maxn],cnt;
    int size[maxn],fa[maxn],dep[maxn],son[maxn];
    int top[maxn],id[maxn];
    int root,ls[maxn<<1],rs[maxn<<1],gcd[maxn<<1];
    int cx[maxn];
    struct edge{
        int y,next;
    }e[maxn<<1];
    
    template<class T>inline void read(T &x){
        x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    } 
    
    void addedge(int x,int y){
        e[++cnt]=(edge){y,head[x]};
        head[x]=cnt;
    }
    
    void dfs(int u){
        size[u]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].y;
            if(v==fa[u]) continue;
            fa[v]=u;
            dep[v]=dep[u]+1;
            dfs(v);
            size[u]+=size[v];
            if(size[v]>size[son[u]]) son[u]=v;
        }
    }
    
    void dfs(int u,int tp){
        id[u]=++cnt;
        aa[cnt]=a[u];
        top[u]=tp;
        if(!son[u]) return ;
        dfs(son[u],tp);
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].y;
            if(v==fa[u]||v==son[u]) continue;
            dfs(v,v);
        }
    }
    
    void add(int x,int val){for(;x<=n;x+=x&-x) cx[x]+=val;}
    int sum(int x){
        int ret=0;
        for(;x;x-=x&-x)
         ret+=cx[x];
        return ret;
    }
    
    int get_gcd(int a,int b){
        return !b ? a : get_gcd(b,a%b);
    }
    
    void update(int rt){
        gcd[rt]=get_gcd(gcd[ls[rt]],gcd[rs[rt]]);
    }
    
    void build(int &rt,int l,int r){
        rt=++cnt;
        if(l==r) {gcd[rt]=aa[l];return ;}
        int mid=(l+r)>>1;
        build(ls[rt],l,mid);
        build(rs[rt],mid+1,r);
        update(rt);
    }
    
    int query(int rt,int l,int r,int a_l,int a_r){
        if(a_r<a_l) return 0;
        if(a_l<=l&&r<=a_r) return gcd[rt];
        int mid=(l+r)>>1;
        if(a_r<=mid) return query(ls[rt],l,mid,a_l,a_r);
        if(mid<a_l) return query(rs[rt],mid+1,r,a_l,a_r);
        return get_gcd(query(ls[rt],l,mid,a_l,a_r),query(rs[rt],mid+1,r,a_l,a_r));
    }
    
    int query(int x,int y){
        int ans=0,ret;
        while(top[x]!=top[y]){
            if(dep[top[x]]>dep[top[y]]) swap(x,y);
            ret=abs(get_gcd(sum(id[top[y]]),query(1,1,n,id[top[y]]+1,id[y])));
            ans=get_gcd(ret,ans);
            y=fa[top[y]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        ret=abs(get_gcd(sum(id[x]),query(1,1,n,id[x]+1,id[y])));
        return get_gcd(ans,ret);
    }
    
    void modify(int rt,int l,int r,int pos,int val){
        if(l==r){
            gcd[rt]+=val;
            return ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) modify(ls[rt],l,mid,pos,val);
        else modify(rs[rt],mid+1,r,pos,val);
        update(rt);
    }
    
    void modify(int x,int y,int val){
        while(top[x]!=top[y]){
            if(dep[top[x]]>dep[top[y]]) swap(x,y);
            add(id[top[y]],val);
            add(id[y]+1,-val);
            modify(1,1,n,id[top[y]],val);
            if(id[y]<n) modify(1,1,n,id[y]+1,-val);
            y=fa[top[y]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        add(id[x],val);
        add(id[y]+1,-val);
        modify(1,1,n,id[x],val);
        if(id[y]<n) modify(1,1,n,id[y]+1,-val);
    }
    
    int main(){
        read(n);
        for(int i=1;i<n;i++){
            int x,y;
            read(x);read(y);
            x++;y++;
            addedge(x,y);addedge(y,x);
        }
        cnt=0;
        for(int i=1;i<=n;i++) read(a[i]);
        dep[1]=1;
        dfs(1);
        dfs(1,1);
        for(int i=n;i;i--) aa[i]-=aa[i-1],add(i,aa[i]);
        cnt=0;
        build(root,1,n);
        read(m);
        for(int i=1;i<=m;i++){
            char op[2];
            int x,y;
            scanf("%s",op);
            read(x);read(y);x++;y++;
            if(op[0]=='F') printf("%d
    ",query(x,y));
            else {
                int val;
                read(val);
                modify(x,y,val);
            }
        }
    }
    View Code
  • 相关阅读:
    一次优化web项目的经历记录(一)
    自己做的萌萌哒的js宠物挂件~
    最近的两个小项目,2:Python webapp的docker镜像
    最近的两个小项目,1:在Vscode里写C/C++
    Markdown写接口文档,自动添加TOC
    使用SqlAlchemy时如何方便的取得dict数据、dumps成Json
    【漏洞预警】SaltStack远程命令执行(CVE-2020-11651、CVE-2020-11652) 植入挖矿木马的应急响应 salt-minions salt-store挖矿程序跑满cpu
    pycharm 常用配置
    gitlab + jenkins + docker + k8s
    Microservice 概念
  • 原文地址:https://www.cnblogs.com/sto324/p/11240909.html
Copyright © 2011-2022 走看看