zoukankan      html  css  js  c++  java
  • BZOJ3306: 树

    n<=1e5的有根点权树,m<=1e5个操作:换根,修改点权,查询子树最小值。

    维护子树信息--dfs序,至于换根只需要分类讨论一下现在根和查询点的关系。

    如果查询的点是根节点,就输出整颗树的最小值。

    如果查询的点5在1到7的路径上,那以7为根的时候查询5,就是整颗树排除粉红色部分--5的儿子中,是7的祖先的那棵子树,就是5的儿子中能走到7的那一个对应的子树。

    其他情况,直接输出查询的子树。

    所以再写一个lca就行了,这里写了链剖可以顺便把dfs序搞出来。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 //#include<assert.h>
      5 #include<math.h>
      6 #include<algorithm>
      7 //#include<iostream>
      8 using namespace std;
      9  
     10 int n,m;
     11 #define maxn 200011
     12 struct Edge{int to,next;}edge[maxn<<1];int first[maxn],val[maxn],le=2;
     13 void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;}
     14 void insert(int x,int y) {in(x,y);in(y,x);}
     15 int size[maxn],hea[maxn],fa[maxn],top[maxn],dep[maxn],list[maxn],lp[maxn],rp[maxn],ll;
     16 void dfs1(int x,int f)
     17 {
     18     fa[x]=f;dep[x]=dep[f]+1;
     19     size[x]=1;hea[x]=0;
     20     for (int i=first[x];i;i=edge[i].next)
     21     {
     22         const Edge &e=edge[i];if (e.to==f) continue;
     23         dfs1(e.to,x);
     24         size[x]+=size[e.to];
     25         if (size[hea[x]]<size[e.to]) hea[x]=e.to;
     26     }
     27 }
     28 void dfs2(int x,int from)
     29 {
     30     top[x]=from;
     31     list[++ll]=x;lp[x]=ll;
     32     if (hea[x]) dfs2(hea[x],from);
     33     for (int i=first[x];i;i=edge[i].next)
     34     {
     35         const Edge &e=edge[i];if (e.to==hea[x] || e.to==fa[x]) continue;
     36         dfs2(e.to,e.to);
     37     }
     38     rp[x]=ll;
     39 }
     40 void treecut()
     41 {
     42     dep[0]=fa[0]=size[0]=ll=0;
     43     dfs1(1,0);
     44     dfs2(1,1);
     45 }
     46 int lca(int x,int y)
     47 {
     48     while (top[x]!=top[y])
     49     {
     50         if (dep[top[x]]<dep[top[y]]) {int t=x;x=y;y=t;}
     51         x=fa[top[x]];
     52     }
     53     return dep[x]<dep[y]?x:y;
     54 }
     55 int findimp(int x,int y)
     56 {
     57     int last;
     58     while (top[x]!=top[y])
     59     {
     60         last=top[y];
     61         y=fa[top[y]];
     62     }
     63     if (x==y) return last;
     64     return list[lp[x]+1];
     65 }
     66 struct SMT
     67 {
     68     struct Node
     69     {
     70         int Min;
     71         int l,r;
     72         int ls,rs;
     73     }a[maxn<<1];
     74     int size;
     75     SMT() {size=0;}
     76     void up(int x)
     77     {
     78         const int &p=a[x].ls,&q=a[x].rs;
     79         a[x].Min=min(a[p].Min,a[q].Min);
     80     }
     81     void build(int &x,int L,int R)
     82     {
     83         x=++size;
     84         a[x].l=L;a[x].r=R;
     85         if (L==R)
     86         {
     87             a[x].Min=val[list[L]];
     88             a[x].ls=a[x].rs=0;
     89         }
     90         else
     91         {
     92             const int mid=(L+R)>>1;
     93             build(a[x].ls,L,mid);
     94             build(a[x].rs,mid+1,R);
     95             up(x);
     96         }
     97     }
     98     void build() {int x;build(x,1,n);}
     99     int ql,qr,v;
    100     void be(int x)
    101     {
    102         if (a[x].l==a[x].r && a[x].l==ql) {a[x].Min=v;return;}
    103         const int mid=(a[x].l+a[x].r)>>1;
    104         if (ql<=mid) be(a[x].ls);
    105         else be(a[x].rs);
    106         up(x);
    107     }
    108     void be(int x,int v)
    109     {
    110         ql=x;this->v=v;
    111         be(1);
    112     }
    113     int query(int x)
    114     {
    115         if (ql<=a[x].l && a[x].r<=qr) return a[x].Min;
    116         const int mid=(a[x].l+a[x].r)>>1;
    117         int ans=0x3f3f3f3f;
    118         if (ql<=mid) ans=min(ans,query(a[x].ls));
    119         if (qr> mid) ans=min(ans,query(a[x].rs));
    120         return ans;
    121     }
    122     int query(int L,int R)
    123     {
    124         if (L>R) return 0x3f3f3f3f;
    125         ql=L;qr=R;
    126         return query(1);
    127     }
    128 }t;
    129 int nowroot;
    130 int main()
    131 {
    132     scanf("%d%d",&n,&m);
    133     int x,y;char s[3];
    134     memset(first,0,sizeof(first));
    135     for (int i=1;i<=n;i++)
    136     {
    137         scanf("%d%d",&x,&y);
    138         if (x) insert(x,i);
    139         val[i]=y;
    140     }
    141     treecut();
    142     t.build();
    143     nowroot=1;
    144     while (m--)
    145     {
    146         scanf("%s",s);
    147         if (s[0]=='E') scanf("%d",&nowroot);
    148         else if (s[0]=='V') scanf("%d%d",&x,&y),t.be(lp[x],y);
    149         else if (s[0]=='Q')
    150         {
    151             scanf("%d",&x);
    152             if (x==nowroot) printf("%d
    ",t.query(1,n));
    153             else
    154             {
    155                 int l=lca(x,nowroot);
    156                 if (l==nowroot || (l!=x && l!=nowroot)) printf("%d
    ",t.query(lp[x],rp[x]));
    157                 else
    158                 {
    159                     int tmp=findimp(x,nowroot);
    160                     printf("%d
    ",min(t.query(1,lp[tmp]-1),t.query(rp[tmp]+1,n)));
    161                 }
    162             }
    163         }
    164     }
    165     return 0;
    166 }
    167 
    View Code
  • 相关阅读:
    asp.net留言板项目源代码下载
    HoverTree项目添加了查看留言列表功能
    HoverTree开源项目已经实现管理员登录
    HoverTree项目已经实现分层
    c# 连接Mysql数据库
    单行文字滚动就用myslider
    C#播放MP3源代码
    PHP 判断是否为 AJAX 请求
    c# TCP Socket通讯基础
    javascript类型注意事项
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7691289.html
Copyright © 2011-2022 走看看