遥远的国度 (【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(){ ;}
阅读全文
0 0
- 遥远的国度 (【bzoj3306】树)
- 【bzoj 3083】遥远的国度(树链剖分+线段树)
- bzoj3083 遥远的国度 树链剖分+线段树
- [BZOJ3083]遥远的国度-树链剖分-线段树
- bzoj3083遥远的国度 树链剖分+线段树
- 遥远国度的呼唤
- bzoj3083: 遥远的国度
- [bzoj3083]遥远的国度
- BZOJ3083: 遥远的国度
- 3083: 遥远的国度
- bzoj3083 遥远的国度
- BZOJ3083遥远的国度
- 【bzoj3083】 遥远的国度
- 【Bzoj3083】遥远的国度
- bzoj3083 遥远的国度
- HYSBZ3083-遥远的国度
- 【BZOJ 3083】遥远的国度
- 【bzoj3083】【遥远的国度】【树链剖分】
- 弹性盒布局、多列布局、媒体查询
- Ubuntu下leveldb的安装使用(C++中)
- hdu-1806:Frequent values(线段树区间合并)
- 51nod 1791 合法括号子段 DP
- CodeForces
- 遥远的国度 (【bzoj3306】树)
- laravel中的模型关系
- Glide出现的相关错误,以及glide4.0的使用
- Arduino Uno 水里水里去火里火里去 可高温防水 MAX6675热电偶温度传感器
- Web踩坑日记
- 指针与数组
- Java通过cal.get(Calendar.MONTH)比真实月份少了一个月
- 再谈HTTP通信
- Window下XGBoost安装