「BZOJ3083」 遥远的国度

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 5551  Solved: 1624
Description

描述
zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度。当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务后才能进入遥远的国度继续追杀。

问题是这样的:遥远的国度有n个城市,这些城市之间由一些路连接且这些城市构成了一颗树。这个国度有一个首都,我们可以把这个首都看做整棵树的根,但遥远的国度比较奇怪,首都是随时有可能变为另外一个城市的。遥远的国度的每个城市有一个防御值,有些时候RapiD会使得某两个城市之间的路径上的所有城市的防御值都变为某个值。RapiD想知道在某个时候,如果把首都看做整棵树的根的话,那么以某个城市为根的子树的所有城市的防御值最小是多少。由于RapiD无法解决这个问题,所以他拦住了zcwwzdjn希望他能帮忙。但zcwwzdjn还要追杀sb的zhx,所以这个重大的问题就被转交到了你的手上。

Input

第1行两个整数n m,代表城市个数和操作数。
第2行至第n行,每行两个整数 u v,代表城市u和城市v之间有一条路。
第n+1行,有n个整数,代表所有点的初始防御值。
第n+2行一个整数 id,代表初始的首都为id。
第n+3行至第n+m+2行,首先有一个整数opt,如果opt=1,接下来有一个整数id,代表把首都修改为id;如果opt=2,接下来有三个整数p1 p2 v,代表将p1 p2路径上的所有城市的防御值修改为v;如果opt=3,接下来有一个整数 id,代表询问以城市id为根的子树中的最小防御值。

Output


对于每个opt=3的操作,输出一行代表对应子树的最小点权值。

Sample Input

3 7
1 2
1 3
1 2 3
1
3 1
2 1 1 6
3 1
2 2 2 5
3 1
2 3 3 4
3 1

Sample Output

1
2
3
4
提示
对于20%的数据,n<=1000 m<=1000。
对于另外10%的数据,n<=100000,m<=100000,保证修改为单点修改。
对于另外10%的数据,n<=100000,m<=100000,保证树为一条链。
对于另外10%的数据,n<=100000,m<=100000,没有修改首都的操作。
对于100%的数据,n<=100000,m<=100000,0<所有权值<=2^31。


/**************************************************************

    Problem: 3083

    User: ictsing

    Language: C++

    Result: Accepted

    Time:3324 ms

    Memory:239704 kb

****************************************************************/

 

//BZOJ3083 遥远的国度

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

const int mt = 2000000+5;

const int inf = (1<<31)-1 ;

inline int read()

{

    int num=0,flag=1;

    char ch;

    do{

        ch=getchar();

        if(ch=='-') flag=-1;

    }while(ch<'0'||ch>'9');

    do{

        num=num*10+ch-'0';

        ch=getchar();

    }while(ch>='0'&&ch<='9');

    return num*flag;

}

int n,m;

int ecnt=0;

int top[mt];

int to[mt<<1],nxt[mt<<1],adj[mt];

int minn[mt<<3],chg[mt<<3];

int fa[mt],val[mt],id[mt],last[mt],dep[mt],opt[mt],fp[mt],sz[mt];

int tim=0;

void adde(int u,int v)

{

    ecnt++,to[ecnt]=v,nxt[ecnt]=adj[u],adj[u]=ecnt;

}

void dfs1(int u)

{

    sz[u]=1,dep[u]=dep[fa[u]]+1;

    for(int i=adj[u];i;i=nxt[i])

    {

        int v=to[i];

        if(fa[u]==v) continue;

        fa[v]=u;

        dfs1(v);

        sz[u]+=sz[v];

        if(sz[v]>sz[opt[u]])

            opt[u]=v;

    }

}

void dfs2(int u,int chain)

{

    top[u]=chain;id[u]=++tim,fp[tim]=u;

    if(opt[u]) dfs2(opt[u],chain);

    for(int i=adj[u];i;i=nxt[i])

    {

        int v=to[i];

        if(v^opt[u]&&v^fa[u])

            dfs2(v,v);

    }

    last[u]=tim;

}

void pushup(int rt)

{

    if(rt) minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);

}

void pushdown(int rt)

{

    if(chg[rt])

    {

        minn[rt<<1]=minn[rt<<1|1]=chg[rt];

        chg[rt<<1]=chg[rt<<1|1]=chg[rt];

        chg[rt]=0;

    }

}

void build(int rt,int l,int r)

{

    if(l==r)

    {

        minn[rt]=val[fp[l]];

        //cout<<l<<" "<<rt<<" "<<val[l]<<" ??? "<<endl;

        chg[rt]=0;

        return ;

    }

    int mid=(l+r)>>1;

    build(rt<<1,l,mid);

    build(rt<<1|1,mid+1,r);

    pushup(rt);

    //cout<<l<<" "<<r<<" "<<rt<<" "<<minn[rt]<<" tut "<<endl;    

}

void change(int rt,int l,int r,int lft,int rgt,int c)

{

    //cout<<lft<<" fuck "<<rgt<<endl;

    //cout<<rt<<endl;

    if(lft<=l&&r<=rgt)

    {

        minn[rt]=c;

        chg[rt]=c;

        //if(lft==2) cout<<" qaq "<<minn[rt]<<endl;

        return ;

    }

    pushdown(rt);

    int mid=(l+r)>>1;

    if(lft<=mid) change(rt<<1,l,mid,lft,rgt,c);

    if(rgt>mid) change(rt<<1|1,mid+1,r,lft,rgt,c);

    pushup(rt);

    //cout<<l<<" "<<r<<" "<<rt<<" "<<minn[rt]<<" qwq "<<endl;

}

void lca_chg(int x,int y,int c)

{

    //cout<<x<<" "<<y<<" "<<c<<endl;

    while(top[x]^top[y])

    {

        if(dep[top[x]]<dep[top[y]]) swap(x,y);

        change(1,1,n,id[top[x]],id[x],c);

        x=fa[top[x]];

    }

    if(dep[x]<dep[y]) swap(x,y);

    change(1,1,n,id[y],id[x],c);

}

int que(int rt,int l,int r,int lft,int rgt)

{

    if(lft>rgt) return inf;

    if(lft<=l&&r<=rgt)

    {

        return minn[rt];

    }

    pushdown(rt);

    int mid=(l+r)>>1;

    int res=inf;

    if(lft<=mid) res=min(res,que(rt<<1,l,mid,lft,rgt));

    if(rgt>mid) res=min(res,que(rt<<1|1,mid+1,r,lft,rgt));

    return res;

}

int root=0;

int main()

{

    n=read(),m=read();

    for(int i=1;i<=n-1;i++)

    {

        int u=read(),v=read();

        adde(u,v),adde(v,u);

    }

    for(int i=1;i<=n;i++)

      val[i]=read();

    int xx;scanf("%d",&xx);root=xx;

    dfs1(xx);

    dfs2(xx,xx);

    build(1,1,n);

    while(m--)

    {

        int opt=read();

        if(opt==1) scanf("%d",&root);

        else if(opt==2) 

        {

            int u=read(),v=read(),x=read();

            //cout<<u<<" "<<v<<" "<<x<<" fuck "<<endl;

            lca_chg(u,v,x);

        }

        else

        {

            int x=read();

            if(x==root) printf("%d\n",que(1,1,n,1,n));

            else if(fa[root]==x) printf("%d\n",min(que(1,1,n,1,id[root]-1),last[root]==n?inf:que(1,1,n,last[root]+1,n)));

            else if(id[root]>=id[x]&&id[root]<=last[x])

            {

                int y=root;

                while(fa[top[y]]!=x&&top[y]^top[x]) y=fa[top[y]];

                if(fa[top[y]]==x) y=top[y];

                else y=fp[id[x]+1];

                printf("%d\n",min(que(1,1,n,1,id[y]-1),last[y]==n?inf:que(1,1,n,last[y]+1,n)));

            }

            else printf("%d\n",que(1,1,n,id[x],last[x]));

        }

    }

    return 0;

}

 


评论

热度(6)