zoukankan      html  css  js  c++  java
  • bzoj3083 遥远的国度 题解

    题目大意:

      给定一棵有根树,每个点有一个权值,提供三种操作:

      1.将x节点变为根节点

      2.将x到y路径上的点的权值全部改为v

      3.询问x的子树中点权的最小值

    思路:

      用DFS序剖分,记录每个节点入栈出栈的时间,其之间的区间即为子树。操作2用线段树直接搞,而换根先不管,可用原来的DFS序。询问时分类讨论:记最开始的根为root,换根之后,对于当前的根rtnow和询问子树U而言,

      ①rtnow==U,询问整棵树

      ②fa[rtnow]==U,询问除了rtnow所在子树以外的整棵树

      ③rtnow在U的子树里,且距离大于1,询问除了rtnow的除了其祖先是U的儿子的祖先的子树以外的整棵树

      ④rtnow不在U的子树里,询问U的子树

    代码:

      1 #include<cstdio>
      2 #include<iostream>
      3 #define M 2000000
      4 #define INF 2147483647
      5 using namespace std;
      6 
      7 int cnt,dfn,n,m,a[M],to[M],hson[M],next[M],head[M],id[M],size[M],last[M],pos[M],pa[M],deep[M],top[M],cov[M<<2],minv[M<<2];
      8 
      9 void ins(int x,int y)
     10 {
     11      to[++cnt]=y,next[cnt]=head[x],head[x]=cnt;
     12 }
     13 
     14 void dfs1(int x)
     15 {
     16     size[x]=1;
     17     for (int i=head[x];i;i=next[i])
     18         if (to[i]!=pa[x])
     19         {
     20             pa[to[i]]=x,deep[to[i]]=deep[x]+1;
     21             dfs1(to[i]),size[x]+=size[to[i]];
     22             if (size[to[i]]>size[hson[x]]) hson[x]=to[i];
     23         }
     24 }
     25 
     26 void dfs2(int x,int tp)
     27 {
     28     id[x]=++dfn,pos[dfn]=x,top[x]=tp;
     29     if (hson[x]) dfs2(hson[x],tp);
     30     for (int i=head[x];i;i=next[i])
     31         if (to[i]!=pa[x]&&to[i]!=hson[x]) dfs2(to[i],to[i]);
     32     last[x]=dfn;
     33 }
     34 
     35 void push_down(int k)
     36 {
     37      if (cov[k])
     38      {
     39          cov[k<<1]=cov[k<<1|1]=minv[k<<1]=minv[k<<1|1]=cov[k];
     40          cov[k]=0;
     41      }
     42 }
     43 
     44 void change(int cur,int L,int R,int l,int r,int val)
     45 {
     46      if (L==l && R==r) { cov[cur]=minv[cur]=val; return; }
     47      int mid=L+R>>1; push_down(cur);
     48      if (r<=mid) change(cur<<1,L,mid,l,r,val);
     49      else if (l>mid) change(cur<<1|1,mid+1,R,l,r,val);
     50           else change(cur<<1,L,mid,l,mid,val),change(cur<<1|1,mid+1,R,mid+1,r,val);
     51      minv[cur]=min(minv[cur<<1],minv[cur<<1|1]);
     52 }
     53 
     54 int ask(int cur,int L,int R,int l,int r)
     55 {
     56     if (L==l && R==r) return minv[cur];
     57     int mid=L+R>>1; push_down(cur);
     58     if (r<=mid) return ask(cur<<1,L,mid,l,r);
     59     if (l>mid) return ask(cur<<1|1,mid+1,R,l,r);
     60     return min(ask(cur<<1,L,mid,l,mid),ask(cur<<1|1,mid+1,R,mid+1,r));
     61 }
     62 
     63 void add(int x,int y,int val)
     64 {
     65      for (;top[x]!=top[y];x=pa[top[x]])
     66      {
     67          if (deep[top[x]]<deep[top[y]]) swap(x,y);
     68          change(1,1,n,id[top[x]],id[x],val);
     69      }
     70      if (deep[x]>deep[y]) swap(x,y);
     71      change(1,1,n,id[x],id[y],val);
     72 }
     73 
     74 int main()
     75 {
     76     scanf("%d%d",&n,&m);
     77     int i,x,y,z,op,rt,root=0;
     78     for (i=1;i<n;i++) scanf("%d%d",&x,&y),ins(x,y),ins(y,x);
     79     for (i=1;i<=n;i++) scanf("%d",&a[i]);
     80     scanf("%d",&rt);dfs1(rt),dfs2(rt,rt);
     81     for (i=1;i<=n;i++) change(1,1,n,id[i],id[i],a[i]);
     82     while (m--)
     83     {
     84           scanf("%d",&op);
     85           if (op==1) scanf("%d",&root);
     86           if (op==2) scanf("%d%d%d",&x,&y,&z),add(x,y,z);
     87           if (op==3)
     88           {
     89                scanf("%d",&x);
     90                if (x==root) printf("%d
    ",ask(1,1,n,1,n));
     91                else if (pa[root]==x) printf("%d
    ",min(ask(1,1,n,1,id[root]-1),last[root]==n?INF:ask(1,1,n,last[root]+1,n)));
     92                     else if (id[root]>=id[x] && id[root]<=last[x])
     93                          {
     94                               y=root;
     95                               while (pa[top[y]]!=x && top[x]!=top[y]) y=pa[top[y]];
     96                               if (pa[top[y]]!=x) y=pos[id[x]+1];
     97                               else y=top[y];
     98                               printf("%d
    ",min(ask(1,1,n,1,id[y]-1),last[y]==n?INF:ask(1,1,n,last[y]+1,n)));
     99                          }
    100                          else printf("%d
    ",ask(1,1,n,id[x],last[x]));
    101           }
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    Atitit 华为基本法 attilax读后感
    Atitit 华为管理者内训书系 以奋斗者为本 华为公司人力资源管理纲要 attilax读后感
    Atitit 项目版本管理gitflow 与 Forking的对比与使用
    Atitit 管理的模式扁平化管理 金字塔 直线型管理 垂直管理 水平管理 矩阵式管理 网状式样管理 多头管理 双头管理
    Atitit 乌合之众读后感attilax总结 与读后感结构规范总结
    深入理解 JavaScript 异步系列(4)—— Generator
    深入理解 JavaScript 异步系列(3)—— ES6 中的 Promise
    深入理解 JavaScript 异步系列(2)—— jquery的解决方案
    深入理解 JavaScript 异步系列(1)——基础
    使用 github + jekyll 搭建个人博客
  • 原文地址:https://www.cnblogs.com/HHshy/p/5823389.html
Copyright © 2011-2022 走看看