zoukankan      html  css  js  c++  java
  • poj3237树链剖分边权+区间取负

    树链剖分+线段树lazy-tag
    在树链上操作时千万不要写错。。

    /*
    树链剖分+线段树区间变负
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define maxn 10005
    struct Edge{
        int to,next;
    }edge[maxn<<1];
    int head[maxn],tot,e[maxn][3];
    int fa[maxn],son[maxn],num[maxn],deep[maxn];
    int top[maxn],fp[maxn],p[maxn],pos;
    inline void addedge(int u,int v){
        edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
    }
    void dfs1(int u,int pre,int dep){
        fa[u]=pre;num[u]=1;deep[u]=dep;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v==pre) continue;
            dfs1(v,u,dep+1);
            num[u]+=num[v];
            if(son[u]==-1 || num[son[u]]<num[v]) son[u]=v;
        }
    }
    void getpos(int u,int sp){
        top[u]=sp;p[u]=pos++;fp[p[u]]=u;
        if(son[u]==-1) return;
        getpos(son[u],sp);
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v!=fa[u] && v!=son[u]) getpos(v,v);
        }
    }
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int Max[maxn<<2],Min[maxn<<2],rev[maxn<<2];//遇到区间取反的通常维护一下区间两个极值
    void build(int l,int r,int rt){
        Max[rt]=Min[rt]=rev[rt]=0;
        if(l==r) return;
        int m=l+r>>1;
        build(lson);build(rson); 
    }
    inline void pushup(int rt){
        Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
        Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
    }
    inline void pushdown(int rt){
        if(rev[rt]){
            rev[rt<<1]^=1,rev[rt<<1|1]^=1;
            swap(Min[rt<<1],Max[rt<<1]);
            Min[rt<<1]*=-1,Max[rt<<1]*=-1;
            swap(Min[rt<<1|1],Max[rt<<1|1]);
            Min[rt<<1|1]*=-1,Max[rt<<1|1]*=-1;
            rev[rt]=0;
        }
    }
    void update(int pos,int val,int l,int r,int rt){
        if(l==r){Max[rt]=Min[rt]=val;rev[rt]=0;return;}
        int m=l+r>>1;
        pushdown(rt);
        if(pos<=m) update(pos,val,lson);
        else update(pos,val,rson);
        pushup(rt);
    }
    void seg_negate(int L,int R,int l,int r,int rt){
        if(L<=l && R>=r){
            swap(Min[rt],Max[rt]);
            Min[rt]*=-1,Max[rt]*=-1;
            rev[rt]^=1;
            return;
        } 
        pushdown(rt);
        int m=l+r>>1;
        if(L<=m) seg_negate(L,R,lson);
        if(R>m) seg_negate(L,R,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt){
        if(L<=l && R>=r)return Max[rt];
        pushdown(rt);
        int m=l+r>>1,res=-100000000;
        if(L<=m) res=max(res,query(L,R,lson));
        if(R>m) res=max(res,query(L,R,rson));
        pushup(rt);
        return res;
    }
    int find(int u,int v)//查询u->v边的最大值
    {
        int f1 = top[u], f2 = top[v];
        int tmp = -100000000;
        while(f1 != f2)
        {
            if(deep[f1] < deep[f2])
            {
                swap(f1,f2);
                swap(u,v);
            }
            tmp = max(tmp,query(p[f1],p[u],0,pos,1));
            u = fa[f1]; f1 = top[u];
        }
        if(u == v)return tmp;
        if(deep[u] > deep[v]) swap(u,v);
        return max(tmp,query(p[son[u]],p[v],0,pos,1));
    }
    void Negate(int u,int v)//把u-v路径上的边的值都设置为val
    {
        int f1 = top[u], f2 = top[v];
        while(f1 != f2)
        {
            if(deep[f1] < deep[f2])
            {
                swap(f1,f2);
                swap(u,v);
            }
            seg_negate(p[f1],p[u],0,pos,1);
            u = fa[f1]; f1 = top[u];
        }
        if(u == v)return;
        if(deep[u] > deep[v]) swap(u,v);
        return seg_negate(p[son[u]],p[v],0,pos,1);
    }
    void init(){
        tot=pos=0;
        memset(head,-1,sizeof head);
        memset(son,-1,sizeof son);
    }
    int main(){
        int T,n,a,b,c;
        char op[10];
        cin >> T;
        while(T--){
            init();
            scanf("%d",&n);
            for(int i=1;i<=n-1;i++){
                scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
                addedge(e[i][0],e[i][1]);addedge(e[i][1],e[i][0]);
            }
            dfs1(1,0,0);getpos(1,1);build(0,pos,1);
            for(int i=1;i<=n-1;i++){
                if(deep[e[i][0]]>deep[e[i][1]]) swap(e[i][0],e[i][1]);
                update(p[e[i][1]],e[i][2],0,pos,1);
            }
    
            while(scanf("%s",op)){
                if(op[0]=='D') break;
                scanf("%d%d",&a,&b);
                if(op[0]=='C')update(p[e[a][1]],b,0,pos,1);
                else if(op[0]=='N') Negate(a,b);
                else printf("%d
    ",find(a,b));
            }
        }
    }
  • 相关阅读:
    Python 递归函数详解
    CentOS7 删除virbr0虚拟网卡
    /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:245: running exec setns .....
    Linux系统添加永久静态路由的方法(包含Centos7)
    正则表达式
    Unity3D -- shader语法内置函数
    Unity3D -- shader光照常用函数和变量
    Unity3D -- shader常用函数和变量
    Unity 着色器训练营(2)
    Unity Shader着色器优化
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10042664.html
Copyright © 2011-2022 走看看