zoukankan      html  css  js  c++  java
  • BZOJ 3083

    原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3083

    说话间又一个多月过去了。。该来除除草了,每天都是训练、没效率,训练、没效率。。省选考得不好不说了=-继续努力吧

    题目大意:维护一棵有根树,支持三个操作:换根; 一条链上都改为一个值; 求某个子树的Min

    算法分析:
    裸的动态树问题,非常简单啦。只涉及链上和子树操作,树的形态没有改变,所以用剖分来搞。就按照最开始给定的那个根剖分,得到一个剖分序。在换根之后查子树的时候注意一件事情,就是在最早的定根的形态中,现在的根如果在要查询的那个子树的根的某个儿子的子树上的话,就需要查询整个树除去这个儿子的子树的最小值,否则就是原来的那个子树的最小值。至于怎么判断,我用剖分序乱搞的=-

    参考代码:

      1 //date 20140521
      2 #include <cstdio>
      3 #include <cstring>
      4 
      5 const int maxn = 105000;
      6 const int INF = 0x7FFFFFFF;
      7 
      8 template <typename T> inline void swap(T &a, T &b){T x = a; a = b; b = x;}
      9 inline int innew(int &a, int b){if(a < b){a = b; return 1;} return 0;}
     10 inline int denew(int &a, int b){if(a > b){a = b; return 1;} return 0;}
     11 inline int min(int a, int b){return a < b ? a : b;}
     12 
     13 inline int getint()
     14 {
     15     int ans(0); char w = getchar();
     16     while(w < '0' || '9' < w) w = getchar();
     17     while('0' <= w && w <= '9')
     18     {
     19         ans = ans * 10 + w - '0';
     20         w = getchar();
     21     }
     22     return ans;
     23 }
     24 
     25 int n, m, root;
     26 struct edge
     27 {
     28     int v, next;
     29 }E[maxn << 1];
     30 int nedge, a[maxn], num[maxn];
     31 
     32 inline void add(int u, int v)
     33 {
     34     E[++nedge].v = v;
     35     E[nedge].next = a[u];
     36     a[u] = nedge;
     37 }
     38 
     39 int dpt[maxn], p[maxn], size[maxn], hp[maxn], hs[maxn];
     40 int order[maxn], ps[maxn], ped[maxn];
     41 
     42 inline void dfs_one(int v0)
     43 {
     44     static int d[maxn], now[maxn];
     45     int last, i, j;
     46     memcpy(now, a, sizeof a);
     47     d[last = dpt[v0] = size[v0] = 1] = v0;
     48     while(last)
     49     {
     50         if(!(j = now[i = d[last]]))
     51         {
     52             if((--last) && (size[d[last]] += size[i], size[hs[d[last]]] < size[i]))
     53                 hs[d[last]] = i;
     54             continue;
     55         }
     56         if(p[i] != E[j].v) dpt[d[++last] = E[j].v] = dpt[p[E[j].v] = i] + (size[E[j].v] = 1);
     57         now[i] = E[j].next;
     58     }
     59 }
     60 
     61 inline void dfs_two(int v0)
     62 {
     63     static int d[maxn], now[maxn];
     64     int last, i, j, tot;
     65     d[last = 1] = order[ps[v0] = ped[v0] = tot = 1] = v0;
     66     memset(now, 0xFF, sizeof now);
     67     for(int i = 1; i <= n; ++i) hp[i] = i;
     68     while(last)
     69     {
     70         if(!(j = now[i = d[last]]))
     71         {
     72             if(--last) innew(ped[d[last]], ped[i]);
     73             continue;
     74         }
     75         if(j == -1)
     76         {
     77             if(hs[i]) hp[d[++last] = order[ps[hs[i]] = ped[hs[i]] = ++tot] = hs[i]] = hp[i];
     78             now[i] = a[i]; continue;
     79         }
     80         if(E[j].v != hs[i] && E[j].v != p[i]) d[++last] = order[ps[E[j].v] = ped[E[j].v] = ++tot] = E[j].v;
     81         now[i] = E[j].next;
     82     }
     83 }
     84 
     85 struct Segment_Tree
     86 {
     87     struct node
     88     {
     89         node *s[2];
     90         int l, r, Min, cov;
     91         node(){}
     92         int cover(int v){Min = v; cov = 1;}
     93         void pushdown()
     94         {
     95             if(cov && l < r){s[0]->cover(Min); s[1]->cover(Min);}
     96             cov = 0; 
     97         }
     98         void update(){ Min = min(s[0]->Min, s[1]->Min);}
     99     }*root, pond[maxn << 1];
    100     int stop;
    101     
    102     void change(node *p, int l, int r, int v)
    103     {
    104         if(l <= p->l && p->r <= r){p->cover(v); return;}
    105         p->pushdown();
    106         int mid = (p->l + p->r) >> 1;
    107         if(l <= mid) change(p->s[0], l, r, v);
    108         if(r >  mid) change(p->s[1], l, r, v);
    109         p->update();
    110     }
    111     
    112     int query(node *p, int l, int r)
    113     {
    114         if(l <= p->l && p->r <= r){return p->Min;}
    115         p->pushdown();
    116         int mid = (p->l + p->r) >> 1;
    117         int ans = INF;
    118         if(l <= mid) denew(ans, query(p->s[0], l, r));
    119         if(r >  mid) denew(ans, query(p->s[1], l, r));
    120         return ans;
    121     }
    122     
    123     node *build(int l, int r)
    124     {
    125         node *p = &pond[stop++];
    126         p->s[0] = p->s[1] = NULL; p->cov = 0; p->l = l; p->r = r;
    127         if(l == r) {p->Min = num[order[l]]; return p;}
    128         int mid = (l + r) >> 1;
    129         p->s[0] = build(l, mid);
    130         p->s[1] = build(mid + 1, r);
    131         p->update();
    132         return p;
    133     }
    134     
    135     void preset(){stop = 0; root = build(1, n);}
    136     
    137     int get_min(int l, int r)
    138     {
    139         if(l > r) swap(l, r);
    140         return query(root, l, r);
    141     }
    142     
    143     void change(int l, int r, int v)
    144     {
    145         if(l > r) swap(l, r);
    146         change(root, l, r, v);
    147     }
    148 }MEOW;
    149 
    150 inline void reroot(int r){root = r;}
    151 inline void change(int x, int y, int v)
    152 {
    153     int x0 = x, y0 = y;
    154     while(hp[x0] != hp[y0])
    155     {
    156         if(dpt[hp[x0]] > dpt[hp[y0]])
    157         {
    158             MEOW.change(ps[hp[x0]], ps[x0], v);
    159             x0 = p[hp[x0]];
    160         }else{
    161             MEOW.change(ps[hp[y0]], ps[y0], v);
    162             y0 = p[hp[y0]];
    163         }
    164     }
    165     MEOW.change(ps[x0], ps[y0], v);
    166 }
    167 inline int query(int x)
    168 {
    169     if(x == root) return MEOW.root->Min;
    170     int x0 = x, r = root, sgn = 1, tp = 0;
    171     if(hp[x0] == hp[r] && dpt[r] > dpt[x]) sgn = 0;
    172     while(hp[x0] != hp[r])
    173     {
    174         if(dpt[hp[x0]] > dpt[hp[r]]) {sgn = 1; break;}
    175         if(p[hp[r]] == x0) tp = hp[r];
    176         sgn = 0; r = p[hp[r]];
    177     }
    178     if(dpt[r] < dpt[x]) sgn = 1;
    179     if(sgn) return MEOW.get_min(ps[x], ped[x]);
    180     if(r != x0) tp = hs[x0];
    181     int ans = MEOW.get_min(1, ps[tp] - 1);
    182     if(ped[tp] != n) denew(ans, MEOW.get_min(ped[tp] + 1, n));
    183     return ans;
    184 }
    185 
    186 int main()
    187 {
    188     freopen("bzoj.in", "r", stdin);
    189     freopen("bzoj.out", "w", stdout);
    190     
    191     n = getint(); m = getint();
    192     for(int i = 1; i < n; ++i)
    193     {
    194         int x = getint(), y = getint();
    195         add(x, y); add(y, x);
    196     }
    197     for(int i = 1; i <= n; ++i) num[i] = getint() - 1;
    198     root = getint();
    199     dfs_one(root); dfs_two(root);
    200     MEOW.preset();
    201     for(int i = 1; i <= m; ++i)
    202     {
    203         int k, x, y, v;
    204         k = getint();
    205         switch(k)
    206         {
    207             case 1: x = getint(); reroot(x); break;
    208             case 2: x = getint(); y = getint(); v = getint() - 1; change(x, y, v); break;
    209             case 3: x = getint(); printf("%u
    ", (unsigned)query(x) + 1u); break;
    210         }
    211     }
    212     return 0;
    213 }
  • 相关阅读:
    Spring配置事务中的 transactionAttributes 各属性含义及XML配置
    91. ExtJS获取父子、兄弟容器元素方法
    90.商城登录页面Extjs
    89. Ext.Button 按钮
    88. [ExtJS2.1教程-5]ToolBar(工具栏)
    87.Ext_菜单组件_Ext.menu.Menu
    86. Ext文本输入框:Ext.form.TextField属性汇总
    85.Ext.Window
    C 一个字符串有三段,第一段原样输出,第二段为要输出字符串的长度,第三段为依据第二段长度补齐第一段
    Spring in action(Spring实战) 第四版中文翻译
  • 原文地址:https://www.cnblogs.com/w007878/p/3742756.html
Copyright © 2011-2022 走看看