问题 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 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
样例输出
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。
【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 0x7fffffff
using 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()
{ ;
}