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
  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/bxd123/p/11417831.html
Copyright © 2011-2022 走看看