BZOJ3306: 树
来源:互联网 发布:鼠标宏编程怎么使用 编辑:程序博客网 时间:2024/05/29 02:46
一开始随便找一个根建树
修改点权在dfs序上改
询问x的子树时,如果x是当前根p的父亲,设y为p的祖先中,x的孩子,那么x的子树就是整棵树除去y的子树范围,否则子树范围不变,在dfs序上找最小值
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void read(int &x){ char c; while(!((c=getchar())>='0'&&c<='9')); x=c-'0'; while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';}inline int _min(const int &x,const int &y){return x<y?x:y;}inline void swap(int &x,int &y){x^=y;y^=x;x^=y;}const int maxn = 110000;const int maxd = 21;int n,m,root;struct edge{ int y,nex; edge(){} edge(const int &_y,const int &_nex){y=_y;nex=_nex;}}a[maxn]; int len,fir[maxn];inline void ins(const int x,const int y){a[++len]=edge(y,fir[x]);fir[x]=len;}int siz[maxn],dep[maxn],fa[maxn][maxd];int id[maxn],dfn,idx[maxn];void dfs(const int x){ siz[x]=1; id[x]=++dfn; idx[dfn]=x; for(int i=1;i<maxd;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for(int k=fir[x];k;k=a[k].nex) { const int y=a[k].y; if(y!=fa[x][0]) { fa[y][0]=x; dep[y]=dep[x]+1; dfs(y); siz[x]+=siz[y]; } }}int LCA(int x,int y,int &son){ if(dep[x]<dep[y]) swap(x,y); for(int i=maxd-1;dep[x]!=dep[y]&&i>=0;i--) if(dep[x]-dep[y]>1<<i) x=fa[x][i]; if(fa[x][0]==y) { son=x; return y; } for(int i=maxd-1;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; son=x; return fa[x][0];}int s[maxn];int seg[maxn<<2];void build_(const int x,const int l,const int r){ if(l==r) { seg[x]=s[idx[l]]; return ; } int mid=l+r>>1,lc=x<<1,rc=lc|1; build_(lc,l,mid); build_(rc,mid+1,r); seg[x]=_min(seg[lc],seg[rc]);}int loc,c;void upd(const int x,const int l,const int r){ if(l==r) { seg[x]=c; return ; } int mid=l+r>>1,lc=x<<1,rc=lc|1; if(loc<=mid) upd(lc,l,mid); else upd(rc,mid+1,r); seg[x]=_min(seg[lc],seg[rc]);}int lx,rx;int query(const int x,const int l,const int r){ if(rx<l||r<lx) return INT_MAX; if(lx<=l&&r<=rx) return seg[x]; int mid=l+r>>1,lc=x<<1,rc=lc|1; return _min(query(lc,l,mid),query(rc,mid+1,r));}int main(){ read(n); read(m); for(int i=1;i<=n;i++) { int fa,v; read(fa); read(v); if(fa) ins(fa,i); else root=i; s[i]=v; } dep[root]=1; dfs(root); build_(1,1,dfn); char str[110]; for(int i=1;i<=m;i++) { scanf("%s",str); if(str[0]=='V') { int x,y; read(x); read(y); loc=id[x]; c=y; s[x]=y; upd(1,1,dfn); continue; } if(str[0]=='E') { int x; read(x); root=x; continue; } if(str[0]=='Q') { int x; read(x); if(root==x) { printf("%d\n",seg[1]); continue; } int f2,f1=LCA(root,x,f2); if(f1==root||f1!=x) { lx=id[x],rx=lx+siz[x]-1; printf("%d\n",query(1,1,dfn)); continue; } if(f1==x) { int ans=s[x]; lx=1,rx=id[f2]-1; if(lx<=rx) ans=_min(ans,query(1,1,dfn)); lx=id[f2]+siz[f2],rx=dfn; if(lx<=rx) ans=_min(ans,query(1,1,dfn)); printf("%d\n",ans); } } } return 0;}
0 0
- 【bzoj3306】树
- bzoj3306 树
- BZOJ3306树
- bzoj3306: 树
- bzoj3306 树
- BZOJ3306: 树
- bzoj3306: 树
- 【bzoj3306】树
- 【bzoj3306】树
- [BZOJ3306]树(dfs序)
- 【bzoj3306】 树 dfs序+线段树
- 【bzoj3306】【树】【dfs序+线段树】
- [bzoj3306]树 dfs序+线段树
- 遥远的国度 (【bzoj3306】树)
- cf588e & bzoj3306 树上倍增
- 树
- 树
- 树
- MySQL中的查询优化技术
- 18->数据文件损坏修复
- 51nod_1384 全排列
- 排序算法(2)--冒泡排序
- 在java导项目的时候出现 java Build Path/configure build path解决办法
- BZOJ3306: 树
- google Android resource
- DB2存储过程(Oracle对比)
- WIN32学习——Windows消息机制(二)
- 文章标题
- input标签多文件上传
- Tensorflow常用优化器
- 一句话,数据库怎么设计
- CoreData 入门级教程,以及注意事项