zoukankan      html  css  js  c++  java
  • P1505 [国家集训队]旅游

    题目链接

    这道题其实还是比较好想的,同样是边权问题。我们需要维护最大值,最小值,和。最坑的地方就是路径上的所有数变相反数,其实这个就是把区间和*-1,区间最大*-1,区间最小*-1,最后pushdown的时候将取反标记^1,接下来一系列都是常规操作。而这里还要记住,单点修改时也要下传lazy标记。而我在跳链的时候写错了调了很久,样例非常之水。

    代码,又臭又长,bzoj上都还AC不了

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e6+7;
    struct node{
        int l,r,sum,mx,lazy1,mi;
    }tree[maxn*6];
    struct node1{
        int nxt,from,to,val;
    }edge[maxn*4];
    int head[maxn],cnt;
    int x,y,v,n,m;
    char opt[666];
    void add(int x,int y,int v){
        edge[++cnt].nxt=head[x];
        edge[cnt].from=x;
        edge[cnt].to=y;
        edge[cnt].val=v;
        head[x]=cnt;
    }
    int ljb[maxn],dep[maxn],son[maxn],fa[maxn],size[maxn],top[maxn],w[maxn],rev[maxn],id[maxn],Time;
    void dfs1(int x,int f){
        dep[x]=dep[f]+1;
        fa[x]=f;
        size[x]=1;
        int maxson=-1;
        for(int i=head[x];i;i=edge[i].nxt){
            int go=edge[i].to;
            if(go==fa[x]) continue;
            w[go]=edge[i].val;
            dfs1(go,x);
            size[x]+=size[go];
            if(size[go]>maxson){
                maxson=size[go];
                son[x]=go;
            }
        }
    }
    void dfs2(int x,int topf){
        top[x]=topf;
        id[x]=++Time;
        rev[id[x]]=w[x];
        if(!son[x]) return;
        dfs2(son[x],topf);
        for(int i=head[x];i;i=edge[i].nxt){
            int go=edge[i].to;
            if(go==fa[x]||go==son[x]) continue;
            dfs2(go,go);
        }
    }
    void pushdown(int now){
        if(tree[now].lazy1){
            tree[now<<1].sum*=-1;
            tree[now<<1|1].sum*=-1;
            swap(tree[now<<1].mx,tree[now<<1].mi);
            tree[now<<1].mx*=-1;
            tree[now<<1].mi*=-1;
            swap(tree[now<<1|1].mx,tree[now<<1|1].mi);
            tree[now<<1|1].mx*=-1;
            tree[now<<1|1].mi*=-1;
            tree[now<<1].lazy1^=1;
            tree[now<<1|1].lazy1^=1;
            tree[now].lazy1=0;
        }
    }
    void pushup(int now){
        tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
        tree[now].mi=min(tree[now<<1].mi,tree[now<<1|1].mi);
        tree[now].mx=max(tree[now<<1].mx,tree[now<<1|1].mx);
    }
    void build(int now,int l,int r){
        tree[now].l=l,tree[now].r=r;
        if(l==r){
            tree[now].mi=tree[now].mx=tree[now].sum=rev[l];
            return;
        }
        int mid=(l+r)>>1;
        build(now<<1,l,mid);
        build(now<<1|1,mid+1,r);
        pushup(now);
    }
    void update1(int now,int x,int v){
        if(tree[now].l==tree[now].r){
            tree[now].mi=tree[now].mx=tree[now].sum=v;
            return;
        }
        pushdown(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        if(x<=mid) update1(now<<1,x,v);
        else update1(now<<1|1,x,v);
        pushup(now);
    }
    void update2(int now,int l,int r){
        if(tree[now].l>=l&&tree[now].r<=r){
            tree[now].sum*=-1;
            tree[now].lazy1^=1;
            swap(tree[now].mi,tree[now].mx);
            tree[now].mi*=-1;
            tree[now].mx*=-1;
            return;
        }
        pushdown(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        if(l<=mid) update2(now<<1,l,r);
        if(r>mid) update2(now<<1|1,l,r);
        pushup(now); 
    }
    void linkup(int x,int y){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            update2(1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        if(dep[x]<dep[y]) swap(x,y);
        update2(1,id[y]+1,id[x]);
    }
    int query1(int now,int l,int r){
        if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum;
        pushdown(now);
        int val=0;
        int mid=(tree[now].l+tree[now].r)>>1;
        if(l<=mid) val+=query1(now<<1,l,r);
        if(r>mid) val+=query1(now<<1|1,l,r);
        return val;
    }
    int query2(int now,int l,int r){
        if(tree[now].l>=l&&tree[now].r<=r) return tree[now].mx;
        pushdown(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        int val=-0x3f3f3f3f;
        if(l<=mid) val=max(val,query2(now<<1,l,r));
        if(r>mid) val=max(val,query2(now<<1|1,l,r));
        return val;
    }
    int query3(int now,int l,int r){
        if(tree[now].l>=l&&tree[now].r<=r) return tree[now].mi;
        pushdown(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        int val=0x3f3f3f3f;
        if(l<=mid) val=min(val,query3(now<<1,l,r));
        if(r>mid) val=min(val,query3(now<<1|1,l,r));
        return val;
    }
    int link1(int x,int y){
        int ans=0;
        if(x==y) return 0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=query1(1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        if(dep[x]<dep[y]) swap(x,y);
        ans+=query1(1,id[y]+1,id[x]);
        return ans;
    }
    int link2(int x,int y){
        int ans=-0x3f3f3f3f;
        if(x==y) return 0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans=max(ans,query2(1,id[top[x]],id[x]));
            x=fa[top[x]];
        }
        if(dep[x]<dep[y]) swap(x,y);
        ans=max(ans,query2(1,id[y]+1,id[x]));
        return ans;
    }
    int link3(int x,int y){
        int ans=0x3f3f3f3f;
        if(x==y) return 0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans=min(ans,query3(1,id[top[x]],id[x]));
            x=fa[top[x]];
        }
        if(dep[x]<dep[y]) swap(x,y);
        ans=min(ans,query3(1,id[y]+1,id[x]));
        return ans;
    }
    int o,p,q;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&x,&y,&v);
            x++;y++;
            add(x,y,v);add(y,x,v);
        }
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%s",opt);
            if(opt[0]=='C'){
                scanf("%d%d",&o,&p);
                int st=edge[o<<1].from;
                int ed=edge[o<<1].to;
                int who=dep[st]<dep[ed]?ed:st;
                update1(1,id[who],p);
            }
            if(opt[0]=='N'){
                scanf("%d%d",&o,&p);
                o++;p++;
                linkup(o,p);
            }
            if(opt[0]=='S'){
                scanf("%d%d",&o,&p);
                o++;p++;
                printf("%d
    ",link1(o,p));
            }
            if(opt[1]=='A'){
                scanf("%d%d",&o,&p);
                o++;p++;
                printf("%d
    ",link2(o,p));
            }
            if(opt[1]=='I'){
                scanf("%d%d",&o,&p);
                o++;p++;
                printf("%d
    ",link3(o,p));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    挖洞经验 | 登录注册表单渗透
    冰蝎v2.0.1核心部分源码浅析
    ThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞
    从一些常见场景到CSRF漏洞利用
    WellCMS 2.0 Beta3 后台任意文件上传
    Redis漏洞利用与防御
    通过主从复制 GetShell 
    他山之石:InfoQ采访Spinellis---如何有效地调试软件
    局部静态变量只能初始化一次是怎么实现?
    CPU工作的基本原理以及如何设计一个简单的16位CPU模型
  • 原文地址:https://www.cnblogs.com/LJB666/p/11371338.html
Copyright © 2011-2022 走看看