zoukankan      html  css  js  c++  java
  • P3979 遥远的国度

    P3979 遥远的国度

    思路

    一开始我用这个函数得到左端点

    int get_l(int x,int y) {
        if(top[x]==top[y]) return son[x];
        int last=top[x];
        while(top[x]!=top[y]) {
            last=top[x];
            x=fa[top[x]];
        }
        if(x==y) return last;
        return son[x];
    }
    

    发现是错误的
    无奈数据太水,还90,bzoj也错了一个点
    debug了一上午
    到现在我也不知道哪里错了,各路好汉看看吧
    也许是我没用dfs序的性质吧
    x的儿子点一定在x的子树范围内child[x] ---- child[x]+siz[child[x]]-1

    代码

    #include <bits/stdc++.h>
    #define ls rt<<1
    #define rs rt<<1|1
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int maxn=5e5+7;
    const int inf=0x7fffffff;
    int read() {
        int x=0,f=1;char s=getchar();
        for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
        for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
        return x*f;
    }
    int n,m,w[maxn];
    int dep[maxn],son[maxn],fa[maxn],siz[maxn];
    int a[maxn],idx[maxn],top[maxn],cnt;
    struct node {
        int v,nxt;
    }e[maxn<<1];
    int head[maxn<<1],tot;
    void add_edge(int u,int v) {
        e[++tot].v=v;
        e[tot].nxt=head[u];
        head[u]=tot;
    }
    namespace seg_tree {
        struct node {
            int l,r,lazy,mi;
        }e[maxn<<2];
        void pushup(int rt) {
            e[rt].mi=min(e[ls].mi,e[rs].mi);
        }
        void pushdown(int rt) {
            if(e[rt].lazy) {
                e[ls].mi=e[rs].mi=e[rt].lazy;
                e[ls].lazy=e[rs].lazy=e[rt].lazy;
                e[rt].lazy=0;
            }
        }
        void build(int l,int r,int rt) {
            e[rt].l=l,e[rt].r=r;
            if(l==r) {
                e[rt].mi=a[l];
                return;
            }
            int mid=(l+r)>>1;
            build(l,mid,ls);
            build(mid+1,r,rs);
            pushup(rt);
        }
        void modify(int L,int R,int k,int rt) {
            if(L<=e[rt].l&&e[rt].r<=R) {
                e[rt].mi=e[rt].lazy=k;
                return;
            }
            pushdown(rt);
            int mid=(e[rt].l+e[rt].r)>>1;
            if(L<=mid) modify(L,R,k,ls);
            if(R>mid) modify(L,R,k,rs);
            pushup(rt);
        }
        int query(int L,int R,int rt) {
            if(R<e[rt].l||e[rt].r<L) return inf;
            if(L<=e[rt].l&&e[rt].r<=R) return e[rt].mi;
            pushdown(rt);
            int mid=(e[rt].l+e[rt].r)>>1;
            int ans=inf;
            if(L<=mid) ans=min(ans,query(L,R,ls));
            if(R>mid) ans=min(ans,query(L,R,rs));
            return ans;
        }
    }
    void dfs1(int u,int f) {
        siz[u]=1;
        fa[u]=f;
        son[u]=0;
        dep[u]=dep[f]+1;
        for(int i=head[u];i;i=e[i].nxt) {
            int v=e[i].v;
            if(v==f) continue;
            dfs1(v,u);
            if(siz[v] > siz[son[u]]) son[u]=v;
            siz[u]+=siz[v];
        }
    }
    void dfs2(int u,int ttt) {
        idx[u]=++cnt;
        a[cnt]=w[u];
        top[u]=ttt;
        if(!son[u]) return;
        dfs2(son[u],ttt);
        for(int i=head[u];i;i=e[i].nxt) {
            if(!idx[e[i].v])
                dfs2(e[i].v,e[i].v);
        }
    }
    void CHANGE(int x,int y,int z) {
        while(top[x]!=top[y]) {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            seg_tree::modify(idx[top[x]],idx[x],z,1);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        seg_tree::modify(idx[x],idx[y],z,1);
    }
    int lca(int x,int y) {
        while(top[x]!=top[y]) {
            if(dep[top[x]] < dep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        return dep[x]<=dep[y] ? x : y;
    }
    int main() {
        n=read(),m=read();
        FOR(i,2,n) {
            int x=read(),y=read();
            add_edge(x,y),add_edge(y,x);
        }
        FOR(i,1,n) w[i]=read();
        int rt=read();
        dfs1(1,0);
        dfs2(1,1);
        seg_tree::build(1,n,1);
        FOR(i,1,m) {
            int opt=read();
            if(opt==1) {
                rt=read();
            } else if(opt==2) {
                int x=read(),y=read(),v=read();
                CHANGE(x,y,v);
            } else if(opt==3) {
                int x=read();
                if(rt==x) {
                    cout<<seg_tree::e[1].mi<<"
    ";
                    continue;
                }
                int tmp=lca(x,rt);
                if(tmp!=x) {
                    cout<<seg_tree::query(idx[x],idx[x]+siz[x]-1,1)<<"
    ";
                } else {
                    int l;
                    for(int i=head[x];i;i=e[i].nxt) {
                            int v=e[i].v;
                            if(idx[v]<=idx[rt]&&idx[v]+siz[v]-1>=idx[rt]){
                                l=v;
                                break;
                            }
                    }
                    int r=l+siz[l];
                    int ans1=inf,ans2=inf;
                    ans1=seg_tree::query(1,idx[l]-1,1);
                    ans2=seg_tree::query(idx[l]+siz[l],n,1);
                    cout<<min(ans1,ans2)<<"
    ";
                }
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    JAVA环境安装配置
    使用apache设置绑定多个域名或网站
    C#资源释放及Dispose、Close和析构方法
    【数据库】百万级数据库SQL优化大总结
    【ABP】Abp的AspNetZero5.0版本无法使用ctrl+f5调式
    【.Net】vs2017 自带发布工具 ClickOnce发布包遇到的问题
    【Python】python 反射机制在实际的应用场景讲解
    【.Net】从字符串数组中寻找数字的元素
    【.Net】输出的字符靠右对齐
    【.Net+数据库】sqlserver的四种分页方式
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10181380.html
Copyright © 2011-2022 走看看