• 2157: 旅游


    题目链接:

    dfs把边权送给点权

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <string>
    using namespace std;
    #define ll long long
    #define re register
    #define pb push_back
    #define fi first
    #define se second
    const int N=1e6+10;
    const int mod=998244353;
    void read(int &a)
    {
        a=0;int d=1;char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    struct node{int x,w,p;};
    struct note
    {
        int l,r,ma,mi,sum,lazy;
    }tree[N<<2];
    vector <node> v[N];
    int siz[N],top[N],dep[N],son[N],id[N],rk[N],f[N],val[N],rt=1,cnt,head[N];
    void dfs1(int x)
    {
        siz[x]=1,dep[x]=dep[f[x]]+1;
        for(re int t=0;t<v[x].size();t++)
        {
            node i=v[x][t];
            if(i.x!=f[x])
            {
                val[i.x]=i.w;
                head[i.p]=i.x;
                f[i.x]=x,dfs1(i.x);
                siz[x]+=siz[i.x];
                if(siz[son[x]]<siz[i.x]) son[x]=i.x;
            }
        }
    }
    void dfs2(int x,int tp)
    {
        top[x]=tp,id[x]=++cnt,rk[cnt]=x;
        if(son[x]) dfs2(son[x],tp);
        for(re int t=0;t<v[x].size();t++) {node i=v[x][t];if(i.x!=son[x]&&i.x!=f[x]) dfs2(i.x,i.x);}
    }
    void build(int l,int r,int now)
    {
        tree[now].l=l,tree[now].r=r,tree[now].lazy=0;
        if(l==r) {tree[now].sum=val[rk[l]],tree[now].ma=val[rk[l]],tree[now].mi=val[rk[l]];return;}
        int m=l+r>>1;
        build(l,m,now<<1),build(m+1,r,now<<1|1);
        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].ma=max(tree[now<<1].ma,tree[now<<1|1].ma);
    }
    void work(int now,int k)
    {
        tree[now].sum=-tree[now].sum;
        int x=tree[now].ma,y=tree[now].mi;
        tree[now].ma=-y,tree[now].mi=-x;
        tree[now].lazy^=k;
    }
    void pushdown(int now)
    {
        work(now<<1,tree[now].lazy);
        work(now<<1|1,tree[now].lazy);
        tree[now].lazy=0;
    }
    void modify(int l,int r,int now,int w)
    {
        if(l<=tree[now].l&&tree[now].r<=r) {work(now,w);return;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) modify(l,r,now<<1,w);
        if(m<r) modify(l,r,now<<1|1,w);
        tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum);
        tree[now].ma=max(tree[now<<1].ma,tree[now<<1|1].ma);
        tree[now].mi=min(tree[now<<1].mi,tree[now<<1|1].mi);
    }
    void mo(int l,int now,int w)
    {
        if(tree[now].l==l&&tree[now].r==l) {tree[now].sum=w,tree[now].ma=w,tree[now].mi=w;return;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) mo(l,now<<1,w);
        if(m<l) mo(l,now<<1|1,w);
        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].ma=max(tree[now<<1].ma,tree[now<<1|1].ma);
    }
    int query(int l,int r,int now)
    {
        int ans=0;
        if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].sum;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) ans+=query(l,r,now<<1);
        if(m<r) ans+=query(l,r,now<<1|1);
        return ans;
    }
    int queryy(int l,int r,int now)
    {
        int ans=-0x3fffffff;
        if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].ma;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) ans=max(ans,queryy(l,r,now<<1));
        if(m<r) ans=max(ans,queryy(l,r,now<<1|1));
        return ans;
    }
    int queryyy(int l,int r,int now)
    {
        int ans=0x3fffffff;
        if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].mi;}
        if(tree[now].lazy) pushdown(now);
        int m=tree[now].l+tree[now].r>>1;
        if(m>=l) ans=min(ans,queryyy(l,r,now<<1));
        if(m<r) ans=min(ans,queryyy(l,r,now<<1|1));
        return ans;
    }
    void update(int x,int y,int w)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            modify(id[top[x]],id[x],1,w);
            x=f[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        modify(id[x]+1,id[y],1,w);
    }
    int query1(int x,int y)
    {
        int ans=0;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=query(id[top[x]],id[x],1);
            x=f[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        return ans+query(id[x]+1,id[y],1);
    }
    int query2(int x,int y)
    {
        int ans=-0x3fffffff;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans=max(ans,queryy(id[top[x]],id[x],1));
            x=f[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        return ans=max(ans,queryy(id[x]+1,id[y],1));
    }
    int query3(int x,int y)
    {
        int ans=0x3fffffff;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans=min(ans,queryyy(id[top[x]],id[x],1));
            x=f[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        return ans=min(ans,queryyy(id[x]+1,id[y],1));
    }
    int main()
    {
        int n;read(n);
        for(re int i=1,x,y,z;i<n;i++)
        {
            read(x),read(y),read(z);
            x++,y++;
            v[x].pb(node{y,z,i});
            v[y].pb(node{x,z,i});
        }
        dfs1(rt),dfs2(rt,rt);
        build(1,n,1);
        int m;read(m);
        char op[10];
        for(re int i=1,l,r;i<=m;i++)
        {
            scanf("%s",op);
            read(l),read(r); l++,r++;
            if(op[0]=='C') l--,r--,mo(id[head[l]],1,r);
            else if(op[0]=='N') update(l,r,1);
            else if(op[0]=='S') printf("%d
    ",query1(l,r));
            else if(op[0]=='M'&&op[1]=='A') printf("%d
    ",query2(l,r));
            else if(op[0]=='M'&&op[1]=='I') printf("%d
    ",query3(l,r));
        }
        return 0;
    }
  • 相关阅读:
    开始接触开源FTP工具 FileZilla
    借船过河:一个据说能看穿你的人性和欲望的心理测试
    Git的使用方法级相关资料
    写给自己的一封信:亲爱的自己
    试用豆瓣电台2天
    HTML5 入门:一个最简单的HTML页面(doctype、meta、Head、标签的使用)
    读《乌合之众》附电子书下载
    快速了解Flash CS5六大特点
    读《每天懂一点成功概率学》
    PhotoshopCS6快捷键
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11901356.html
Copyright © 2020-2023  润新知