zoukankan      html  css  js  c++  java
  • P3979 遥远的国度 树链剖分

      

    题意:

    操作一:将根节点变为x

    操作二:将x到y的点权变为v

    操作三:询问x及其子树中最小点权

    按照1进行树剖即可

    如果 x为根节点  那么输出线段树最小值即可

    如果x不在1-root的路径上  那么正常输出x的子树即可(为+siz) 

    如果x在1-root的路径上  设x在1-root上的儿子节点为y  输出除了 id[y],id[y]+siz[y]-1 的其他部分的最小值即可 也就是  1----d[y]-1   id[y]+siz[y]-----n

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    /////////////////////////////////////
    const int N=1e6+100;
    
    ll minn[N<<2],col[N<<2];
    int n,m,root,T;
    ll w[N],node[N];
    void build(int l,int r,int pos)
    {
        if(l==r){minn[pos]=w[l];return ;}
        int m=(l+r)>>1;
        build(l,m,pos<<1);build(m+1,r,pos<<1|1);
        minn[pos]=min(minn[pos<<1],minn[pos<<1|1]);
    }
    void down(int pos)
    {
        if(!col[pos])return ;
        col[pos<<1|1]=col[pos<<1]=minn[pos<<1]=minn[pos<<1|1]=col[pos];
        col[pos]=0;
    }
    void upsum(int L,int R,ll v,int l,int r,int pos)
    {
        if(L<=l&&r<=R){col[pos]=minn[pos]=v;return ;}
        down(pos);int m=(l+r)>>1;
        if(L<=m)upsum(L,R,v,l,m,pos<<1);
        if(R>m)upsum(L,R,v,m+1,r,pos<<1|1);
        minn[pos]=min(minn[pos<<1],minn[pos<<1|1]);
    }
    ll qmin(int L,int R,int l,int r,int pos)
    {
        if(L<=l&&r<=R)return minn[pos];
        int m=(l+r)>>1;ll ans=inf;down(pos);
        if(L<=m)ans=min(ans,qmin(L,R,l,m,pos<<1));
        if(R>m)ans=min(ans,qmin(L,R,m+1,r,pos<<1|1));
        minn[pos]=min(minn[pos<<1],minn[pos<<1|1]);
        return ans;
    }
    int fa[N][30],id[N],ncnt,dep[N],son[N],siz[N],top[N],head[N],pos;
    struct Edge{int to,nex;}edge[N<<1];
    void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;}
    
    void dfs1(int x,int f)
    {
        fa[x][0]=f;son[x]=0;siz[x]=1;dep[x]=dep[f]+1;
        rep(i,1,T)
        fa[x][i]=fa[fa[x][i-1]][i-1];
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;if(v==f)continue;
            dfs1(v,x);siz[x]+=siz[v];
            if(siz[son[x]]<siz[v])son[x]=v;
        }
    }
    void dfs2(int x,int topf)
    {
        top[x]=topf;id[x]=++ncnt;w[ncnt]=node[x];
        if(son[x])dfs2(son[x],topf);
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;if(v==fa[x][0]||v==son[x])continue;
            dfs2(v,v);
        }
    }
    void UPsum(int x,int y,int v)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            upsum(id[top[x]],id[x],v,1,n,1);
            x=fa[top[x]][0];
        }
        if(dep[x]>dep[y])swap(x,y);
        upsum(id[x],id[y],v,1,n,1);
    }
    int get1(int x,int k)
    {
        repp(i,T,0)
        if(k>=(1<<i))
        k-=(1<<i),x=fa[x][i];
        return x;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);T=log2(n);
        rep(i,1,n-1)
        {
            int a,b;scanf("%d%d",&a,&b);add(a,b);add(b,a);
        }
        rep(i,1,n)scanf("%lld",&node[i]);
        scanf("%d",&root);
        dfs1(1,1);
        dfs2(1,1);
        build(1,n,1);int a,b,c,y;ll d;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(a==1)root=b;
            else if(a==2)scanf("%d%lld",&c,&d),UPsum(b,c,d);
            else
            {
                int x=b;
                if(root==b){printf("%lld
    ",minn[1]);continue;}
                if(dep[x]<dep[root]&&fa[y=get1(root,dep[root]-dep[x]-1)][0]==x)
                {
                    ll p,q;
                    p=qmin(1,id[y]-1,1,n,1);
                    if(id[y]+siz[y]<=n)
                    q=qmin(id[y]+siz[y],n,1,n,1);
                    else q=(1LL<<31)+1;
                    printf("%lld
    ",min(q,p));
                }
                else printf("%lld
    ",qmin(id[x],id[x]+siz[x]-1,1,n,1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    已解决: 已引发: "无法加载 DLL“opencv_core2410”: 找不到指定的模块。
    Xcode 设置图片全屏显示
    独创轻松实现拖拽,改变层布局
    WCF Odata 开放数据协议应用
    MVC中,加入的一个aspx页面用到AspNetPager控件处理办法
    关于 HRESULT:0x80070
    Springboot文件上传大小设置
    Jquery Validate 表单验证使用
    Quartz任务调度框架使用
    js中常见命令
  • 原文地址:https://www.cnblogs.com/bxd123/p/11417831.html
Copyright © 2011-2022 走看看