• BZOJ 1984 月下“毛景树” 树链剖分+线段树


    题意

    bzoj好像把这题删了,在洛谷里找的

    毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。

    爬啊爬爬啊爬毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~ “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数:

    • Change k w:将第k条树枝上毛毛果的个数改变为w个。
    • Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。
    • Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问:
    • Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。

    分析

    把边权转成点权,然后就是树链剖分裸题了,线段树维护下区间最大值就完事了

    Code

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,mid,p<<1
    #define rson mid+1,r,p<<1|1
    using namespace std;
    typedef long long ll;
    const int inf=1e9;
    const int maxn=2e5;
    int n;
    int a[maxn],w[maxn],b[maxn];
    typedef pair<int,int> pii;
    vector<pii>g[maxn];
    int top[maxn],f[maxn],d[maxn],id[maxn],p[maxn],sz[maxn],son[maxn],tot;
    int mx[maxn<<2],t1[maxn<<2],t2[maxn<<2],t3[maxn<<2];
    void pp(int p){mx[p]=max(mx[p<<1],mx[p<<1|1]);}
    void bd(int l,int r,int p){
        t1[p]=-1;
        if(l==r) return mx[p]=a[id[l]],void();
        int mid=l+r>>1;
        bd(lson);bd(rson);pp(p);
    }
    void pd(int p,int a,int b){
        if(a!=-1){
            mx[p]=a;t1[p]=a;t2[p]=0;
        }mx[p]+=b;t2[p]+=b;
    }
    void up(int dl,int dr,int l,int r,int p,int k,int op){
        if(l>=dl&&r<=dr){
            if(op==1){
                mx[p]=k;t1[p]=k;
                t2[p]=0;
            }else{
                mx[p]+=k;t2[p]+=k;
            }
            return;
        }int mid=l+r>>1;
        pd(p<<1,t1[p],t2[p]);pd(p<<1|1,t1[p],t2[p]);t1[p]=-1;t2[p]=0;
        if(dl<=mid) up(dl,dr,lson,k,op);
        if(dr>mid) up(dl,dr,rson,k,op);
        pp(p);
    }
    int qy(int dl,int dr,int l,int r,int p){
        if(l>=dl&&r<=dr) return mx[p];
        int mid=l+r>>1;int ret=-inf;
        pd(p<<1,t1[p],t2[p]);pd(p<<1|1,t1[p],t2[p]);t1[p]=-1;t2[p]=0;
        if(dl<=mid) ret=max(ret,qy(dl,dr,lson));
        if(dr>mid) ret=max(ret,qy(dl,dr,rson));
        return ret;
    }
    void dfs1(int u){
        sz[u]=1;d[u]=d[f[u]]+1;
        for(pii x:g[u]){
            if(x.fi==f[u]) continue;
            f[x.fi]=u;dfs1(x.fi);
            a[x.fi]=w[x.se];b[x.se]=x.fi;sz[u]+=sz[x.fi];
            if(sz[x.fi]>sz[son[u]]) son[u]=x.fi;
        }
    }
    void dfs2(int u,int t){
        top[u]=t;p[u]=++tot;id[tot]=u;
        if(son[u]) dfs2(son[u],t);
        for(pii x:g[u]){
            if(x.fi==f[u]||x.fi==son[u]) continue;
            dfs2(x.fi,x.fi);
        }
    }
    void col(int x,int y,int k,int op){
        while(top[x]!=top[y]){
            if(d[top[x]]<d[top[y]]) swap(x,y);
            up(p[top[x]],p[x],1,n,1,k,op);
            x=f[top[x]];
        }
        if(d[x]<d[y]) swap(x,y);
        up(p[y]+1,p[x],1,n,1,k,op);
    }
    int cal(int x,int y){
        int res=-inf;
        while(top[x]!=top[y]){
            if(d[top[x]]<d[top[y]]) swap(x,y);
            res=max(res,qy(p[top[x]],p[x],1,n,1));
            x=f[top[x]];
        }
        if(d[x]<d[y]) swap(x,y);
        return max(res,qy(p[y]+1,p[x],1,n,1));
    }
    int main(){
        scanf("%d",&n);
        for(int i=1,a,b;i<n;i++){
            scanf("%d%d%d",&a,&b,&w[i]);
            g[a].pb(pii(b,i));g[b].pb(pii(a,i));
        }
        dfs1(1);dfs2(1,1);bd(1,n,1);
        char s[20];
        while(~scanf("%s",s)){
            if(s[0]=='S') break;
            int x,u,v,k;
            if(s[0]=='C'&&s[1]=='h'){
                scanf("%d%d",&x,&k);
                int pos=p[b[x]];
                up(pos,pos,1,n,1,k,1);
            }else if(s[0]=='C'&&s[1]=='o'){
                scanf("%d%d%d",&u,&v,&k);
                col(u,v,k,1);
            }else if(s[0]=='A'){
                scanf("%d%d%d",&u,&v,&k);
                col(u,v,k,2);
            }else{
                scanf("%d%d",&u,&v);
                printf("%d
    ",cal(u,v));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    闭包函数与装饰器
    python 函数的参数
    python 函数定义及调用
    python 文件指针及文件覆盖
    phtnon 文件操作
    Volatile 关键字 内存可见性
    UNION 和 UNION ALL 操作符
    设计模式(七)---- 模板方法模式
    设计模式(六)---- 策略模式
    设计模式(五)---- 原型模式
  • 原文地址:https://www.cnblogs.com/xyq0220/p/10914281.html
Copyright © 2020-2023  润新知