BZOJ 3083 remote country DFS sequence tree Chain Division
Given a tree with a root tree, each vertex has a weight and provides three operations:
1. Change x to the root node.
2. Change the weights of all vertices from x to y to v.
3. Ask the minimum value of the vertex weight in the subtree of x.
Tree link splitting is not discussed! However, because it is the minimum weight of the subtree to be queried, we choose DFS partitioning instead of previous partitioning.
That is, the first son to be traversed on each node is the parent son, and the duplicate number is the DFS order.
Then, if you want to replace the root node, you don't have to record the current root node. Then, we will discuss the problem in three cases.
1. root is in the Child tree of x, but not x. At this time, the child node y of x is enumerated. If root is in the Child tree of y, the Child tree y's complement set is required.
2. root = x is the sub-tree of the root node x, which is the whole tree. At this time, the complete set is output directly.
3. If the root is not in the subtree of x, the minimum weight of the subtree of x is directly output.
A very easy question to write. It took an afternoon to get down ..... RE three times, killed three bugs, and found that freopen was not deleted... The second case is not discussed ..
The final writing is-Ms... Why is it so swollen today...
#include
#include
#include
#include#define ls tree[p].lson#define rs tree[p].rson#define M 100100using namespace std;struct Tree{ int num,mark; int lson,rson;}tree[M<<1];struct abcd{ int to,next;}table[M<<1];int head[M],tot;int n,m,root,treetot,f[M],fa[M],dpt[M],top[M],son[M],pos[M],last[M],posf[M],cnt;void add(int x,int y){ table[++tot].to=y; table[tot].next=head[x]; head[x]=tot;}void dfs(int x){ int i,lastson=0; dpt[x]=dpt[fa[x]]+1; pos[x]=++cnt; if(son[fa[x]]==x) top[x]=top[fa[x]]; else top[x]=x; for(i=head[x];i;i=table[i].next) { if(table[i].to==fa[x]) continue; fa[table[i].to]=x; if(!son[x]) son[x]=table[i].to; lastson=table[i].to; dfs(table[i].to); } if(lastson)last[x]=last[lastson]; else last[x]=pos[x];}void Build_Tree(int p,int x,int y){ int mid=x+y>>1; if(x==y) { tree[p].num=posf[mid]; return ; } ls=++treetot;rs=++treetot; Build_Tree(ls,x,mid); Build_Tree(rs,mid+1,y); tree[p].num=min(tree[ls].num,tree[rs].num);}void update(int p,int x,int y,int l,int r,int v){ int mid=x+y>>1; if(x==l&&y==r) { tree[p].num=tree[p].mark=v; return ; } if(tree[p].mark) { tree[ls].num=tree[ls].mark=tree[p].mark; tree[rs].num=tree[rs].mark=tree[p].mark; tree[p].mark=0; } if(r<=mid) update(ls,x,mid,l,r,v); else if(l>mid) update(rs,mid+1,y,l,r,v); else update(ls,x,mid,l,mid,v),update(rs,mid+1,y,mid+1,r,v); tree[p].num=min(tree[ls].num,tree[rs].num);}void change(int x,int y,int z){ int fx=top[x],fy=top[y]; while(fx!=fy) { if(dpt[fx]
>1; if(x==l&&y==r) return tree[p].num; if(tree[p].mark) { tree[ls].num=tree[ls].mark=tree[p].mark; tree[rs].num=tree[rs].mark=tree[p].mark; tree[p].mark=0; } if(r<=mid) return getans(ls,x,mid,l,r); else if(l>mid) return getans(rs,mid+1,y,l,r); else return min( getans(ls,x,mid,l,mid) , getans(rs,mid+1,y,mid+1,r) );}int query(int x){if(x==root) return getans(0,1,n,1,n); if(pos[root]
last[x]) return getans(0,1,n,pos[x],last[x]); int i,re=0x7fffffff; for(i=head[x];i;i=table[i].next) if(pos[root]>=pos[table[i].to]&&pos[root]<=last[table[i].to]&&table[i].to!=fa[x]) break; re=min(re,getans(0,1,n,1,pos[table[i].to]-1)); if(last[table[i].to]!=n) re=min(re,getans(0,1,n,last[table[i].to]+1,n)); return re;}int main(){ int i,x,y,z,p; cin>>n>>m; for(i=1;i
>root; dfs(root); for(i=1;i<=n;i++) posf[pos[i]]=f[i]; Build_Tree(0,1,n); for(i=1;i<=m;i++) { scanf("%d",&p); if(p==1) scanf("%d",&root); else if(p==2) scanf("%d%d%d",&x,&y,&z),change(x,y,z); else scanf("%d",&x),printf("%d\n",query(x)); }}