遥远的国度 (【bzoj3306】树)

来源:互联网 发布:mac os x 10.10 iso 编辑:程序博客网 时间:2024/05/29 05:12

问题 F: 遥远的国度

时间限制: 1 Sec  内存限制: 128 MB
提交: 60  解决: 18
[提交][状态][讨论版]

题目描述

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

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

输入

第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为根的子树中的最小防御值。

输出


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

样例输入

3 71 21 31 2 313 12 1 1 63 12 2 2 53 12 3 3 43 1

样例输出

1234提示对于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。
【bzoj3306】树
#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#define V 100003#define LL long long//#define maxn#define INF 0x7fffffffusing namespace std;struct data{ int to,from,next;       }Edge[V*10];int L,R,L1,R1;LL add[V*10];int tot,head[V],n,siz[V],son[V],dep[V];int top[V],tot1,ps[V*10];LL mx[V*10];LL id[V],g[V],b[20],f[V][50],v[V];void addedge(int x,int y){   ++tot;  Edge[tot].from=x;  Edge[tot].to=y;   Edge[tot].next=head[x];  head[x]=tot;     }void dfs1(int x){          for(int i=1;i<=20;i++)          if(b[i]<=dep[x])          f[x][i]=f[f[x][i-1]][i-1];          int z;          siz[x]=1;          son[x]=0;          for(int i=head[x];i!=-1;i=Edge[i].next)          {                 z=Edge[i].to;                 if(z!=f[x][0])                 {                    f[z][0]=x;                    dep[z]=dep[x]+1;                    dfs1(z);                    siz[x]+=siz[z];                    if(siz[z]>siz[son[x]])                    son[x]=z;                 }               }}void dfs2(int x,int ss){      int z;      top[x]=ss;      tot1++;      g[x]=id[x]=tot1;      ps[tot1]=x;      if(son[x])      dfs2(son[x],ss);      else return ;      g[x]=max(g[x],g[son[x]]);      for(int i=head[x];i!=-1;i=Edge[i].next)      {            z=Edge[i].to;                 if(z!=f[x][0]&&z!=son[x])         {           dfs2(z,z);            g[x]=max(g[x],g[z]);         }            }}inline void pushdown(int x,int l,int mid,int r){      if(add[x])      {            add[x*2]=add[x];            add[x*2+1]=add[x];            mx[x*2]=add[x];            mx[x*2+1]=add[x];            add[x]=0;                }       }void build(int rt,int l,int r){       if(l==r)       {         mx[rt]=v[ps[l]];         return ;                }        int mid=(l+r)/2;       build(rt*2,l,mid);       build(rt*2+1,mid+1,r);       mx[rt]=min(mx[rt*2],mx[rt*2+1]);   }LL query(int l,int r,int rt){    if(L<=l&&r<=R)    {      return mx[rt];     }    int mid=(l+r)/2;    pushdown(rt,l,mid,r);     LL res=INF;    if(L<=mid)res=min(res,query(l,mid,rt*2));    if(R>mid)res=min(res,query(mid+1,r,rt*2+1));    return res;}void U(LL tt,int rt,int l,int r){      if(L<=l&&R>=r)      {        add[rt]=tt;        mx[rt]=tt;          return ;          }        int mid=(l+r)/2;        pushdown(rt,l,mid,r);     if(L<=mid)     U(tt,rt*2,l,mid);     if(R>mid)     U(tt,rt*2+1,mid+1,r);     mx[rt]=min(mx[rt*2],mx[rt*2+1]);} inline void Q1(int x,int y,LL z){         if(x==y)         {            L=R=id[x];            return U(z,1,1,n);//id[x],id[x],         }       int fx=top[x],fy=top[y],res=0;       while(fx!=fy)       {             if(dep[fx]<dep[fy])             {                swap(x,y);                swap(fx,fy);                            }                     L=id[fx];             R=id[x];                  U(z,1,1,n);//id[fx],id[x],             x=f[fx][0];fx=top[x];       }        if(dep[x]>dep[y])       swap(x,y);       L=id[x];       R=id[y];       U(z,1,1,n);//id[x],id[y],}int sg;LL ddd(){      memset(head,-1,sizeof(head));    memset(mx,127,sizeof(mx));  // freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);  //freopen("bbbbb.in","r",stdin);freopen("bbbbb.out","w",stdout);    //cout<<mx[1]<<"  "<<INF<<endl;     b[0]=1;     for(int i=1;i<=21;i++)      b[i]=b[i-1]<<1;       int m;       int x,y;       scanf("%d%d",&n,&m);      // cin>>n>>m;      for(int i=1;i<n;i++)      {         scanf("%d%d",&x,&y);         addedge(x,y);         addedge(y,x);           }     // cout<<tot;            for(int i=1;i<=n;i++)        scanf("%lld",&v[i]);         //cin>>v[i];         int op;         LL d,gf,z;                   //cin>>sg;          scanf("%d",&sg);          dfs1(sg);          dfs2(sg,sg);          build(1,1,n);// while(1);          //int sf;          for(int i=1;i<=m;i++)              {                      // cin>>op;                      scanf("%d",&op);                       if(op==1)                       {                         scanf("%d",&sg);                             }                               if(op==2)                       {                            //cin>>x>>y>>z;                            scanf("%d%d%lld",&x,&y,&z);                            Q1(x,y,z);                              }                       if(op==3)                       {                          // cin>>x;                          scanf("%d",&x);                           if(x==sg)                           {                            L=1;                            R=n;                            //cout<<"  !!! ";                            printf("%lld\n",query(1,n,1));                                    }                           else if(id[x]<=id[sg]&&g[x]>=g[sg])                           {                                y=sg;                                d=dep[y]-dep[x]-1;                                for(int i=0;i<=20;i++)                                if(b[i]&d)                                y=f[y][i];                                L=1;                                R=id[y]-1;                                gf=INF;                                gf=min(gf,query(1,n,1));                                L=g[y]+1;                                R=n;                                gf=min(gf,query(1,n,1));                                printf("%lld\n",gf);                           }                           else                           {                               L=id[x];                               R=g[x];                                printf("%lld\n",query(1,n,1));                           }                       }                                           }       return 0;        }LL ttt=ddd();int main(){ ;}
原创粉丝点击