zoukankan      html  css  js  c++  java
  • BZOJ3553 [Shoi2014]三叉神经树

    容易想到树链剖分来维护

    一条链上维护儿子中是1的个数为1的点的最长值和儿子是1的个数为2的点的最长值

    于是每次修改的时候就二分查询会更新到哪里,再直接链修改就好了

    单次查询复杂度$O(logn^2)$,单次修改复杂度为$O(logn)$

    注意如果动态开点太多会导致MLE,最后解决办法是在每个线段树节点上增加了一个res变量表示返回值

      1 /**************************************************************
      2     Problem: 3553
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:18880 ms
      7     Memory:102672 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11  
     12 using namespace std;
     13 const int N = 5e5 + 5;
     14  
     15 inline int read();
     16  
     17 int n;
     18 int seq[N * 3];
     19  
     20 struct tree_node {
     21     int v, dep, sz;
     22     int son[3], fa, top, w;
     23 } tr[N * 3];
     24  
     25 struct seg {
     26     seg *ls, *rs, *res;
     27     int tag, mx[2], sz;
     28  
     29     #define Len (1 << 16)
     30     inline void* operator new (size_t) {
     31         static seg *mempool, *c;
     32         if (c == mempool)
     33             mempool = (c = new seg[Len]) + Len;
     34         c -> ls = c -> rs = c -> res = NULL;
     35         c -> tag = -1, c -> sz = 1, c -> mx[0] = c -> mx[1] = 0;
     36         return c++;
     37     }
     38     #undef Len
     39  
     40     inline void fill(int x) {
     41         tag = x;
     42         mx[0] = mx[1] = 0;
     43         if (tag == 1) mx[0] = sz;
     44         if (tag == 2) mx[1] = sz;
     45     }   
     46     inline void push() {
     47         if (tag != -1) {
     48             if (ls) ls -> fill(tag);
     49             if (rs) rs -> fill(tag);
     50             tag = -1;
     51         }
     52     }
     53     inline void update(seg *t1, seg *t2) {
     54         sz = t1 -> sz + t2 -> sz;
     55         mx[0] = t2 -> mx[0] + (t2 -> mx[0] == t2 -> sz ? t1 -> mx[0] : 0);
     56         mx[1] = t2 -> mx[1] + (t2 -> mx[1] == t2 -> sz ? t1 -> mx[1] : 0);
     57     }
     58      
     59     #define mid (l + r >> 1)
     60     void build(int l, int r) {
     61         if (l == r) {
     62             fill(tr[seq[l]].v);
     63             return;
     64         }
     65         ls = new()seg, rs = new()seg, res = new()seg;
     66         ls -> build(l, mid), rs -> build(mid + 1, r);
     67         update(ls, rs);
     68     }
     69      
     70     void modify(int l, int r, int L, int R, int d) {
     71         if (L <= l && r <= R) {
     72             fill(d);
     73             return;
     74         }
     75         push();
     76         if (L <= mid) ls -> modify(l, mid, L, R, d);
     77         if (mid < R) rs -> modify(mid + 1, r, L, R, d);
     78         update(ls, rs);
     79     }
     80      
     81     int query(int l, int r, int pos) {
     82         if (l == r) return tag;
     83         push();
     84         if (pos <= mid) return ls -> query(l, mid, pos);
     85         else return rs -> query(mid + 1, r, pos);
     86     }
     87     seg* query(int l, int r, int L, int R) {
     88         if (L <= l && r <= R) return this;
     89         push();
     90         if (R <= mid) return ls -> query(l, mid, L, R);
     91         if (mid < L) return rs -> query(mid + 1, r, L, R);
     92         res -> update(ls -> query(l, mid, L, R), rs -> query(mid + 1, r, L, R));
     93         return res;
     94     }
     95     #undef mid
     96 } *T;
     97  
     98 inline void modify(int p, int tar, int c) {
     99     while (tr[p].top != tr[tar].top)
    100         T -> modify(1, n, tr[tr[p].top].w, tr[p].w, c), p = tr[tr[p].top].fa;
    101     T -> modify(1, n, tr[tar].w, tr[p].w, c);
    102 }
    103  
    104 int change(int p) {
    105     static int c, now, q;
    106     static seg *tmp;
    107     c = tr[p].v, now = tr[p].fa, tr[p].v = 1 - tr[p].v;
    108     while (1) {
    109         tmp = T -> query(1, n, tr[tr[now].top].w, tr[now].w);
    110         if (tmp -> sz != tmp -> mx[c]) break;
    111         now = tr[now].top;
    112         if (!tr[now].fa || T -> query(1, n, tr[tr[now].fa].w) != c + 1) break;
    113         now = tr[now].fa;
    114     }
    115     if (T -> query(1, n, tr[now].w) != c + 1) {
    116         T -> modify(1, n, tr[now].w, tr[now].w, T -> query(1, n, tr[now].w) + (c ? -1 : 1));
    117         return T -> query(1, n, 1) >= 2;
    118     }
    119     if (now == tr[now].top) q = now;
    120     else q = seq[tr[now].w - T -> query(1, n, tr[tr[now].top].w, tr[now].w) -> mx[c] + 1];
    121     modify(tr[p].fa, q, tr[p].v + 1);
    122     if (tr[q].fa) T -> modify(1, n, tr[tr[q].fa].w, tr[tr[q].fa].w, T -> query(1, n, tr[tr[q].fa].w) + (c ? -1 : 1));
    123     return T -> query(1, n, 1) >= 2;
    124 }
    125  
    126 void get_seq() {
    127     static int i, j, q[N], tot_q, tot_d, p, S;
    128     q[tot_q = 1] = 1, tr[1].fa = 0;
    129     for (i = 1; i <= n; ++i)
    130         for (j = 0; j < 3; ++j)
    131             if (tr[q[i]].son[j] <= n)
    132                 tr[q[++tot_q] = tr[q[i]].son[j]].dep = tr[q[i]].dep + 1;
    133     for (i = 1; i <= n; ++i) tr[i].top = i, tr[i].sz = 1;
    134     for (i = n; i; --i) tr[tr[q[i]].fa].sz += tr[q[i]].sz;
    135      
    136     tr[0].sz = 0, tr[1].w = 1;
    137     for (i = 1; i <= n; ++i) {
    138         p = q[i], tot_d = tr[p].w;
    139         for (j = S = 0; j < 3; ++j)
    140             if (tr[p].son[j] <= n && tr[tr[p].son[j]].sz > tr[S].sz)
    141                 S = tr[p].son[j];
    142         if (S)
    143             tr[S].w = tot_d + 1, tot_d += tr[S].sz, tr[S].top = tr[p].top;
    144         for (j = 0; j < 3; ++j)
    145             if (tr[p].son[j] <= n && tr[p].son[j] != S)
    146                 tr[tr[p].son[j]].w = tot_d + 1, tot_d += tr[tr[p].son[j]].sz;
    147     }
    148     for (i = n; i; --i) if (tr[q[i]].v >= 2) ++tr[tr[q[i]].fa].v;
    149     for (i = 1; i <= n; ++i) seq[tr[i].w] = i;
    150 }
    151  
    152 int main() {
    153     int i, j, Q;
    154     n = read();
    155     for (i = 1; i <= n; ++i)
    156         for (j = 0; j < 3; ++j)
    157             tr[tr[i].son[j] = read()].fa = i;
    158     for (i = n + 1; i <= 3 * n + 1; ++i)
    159         tr[tr[i].fa].v += (tr[i].v = read());
    160     get_seq();
    161     T = new()seg, T -> build(1, n);
    162     Q = read();
    163     while (Q--)
    164         printf("%d
    ", change(read()));
    165     return 0;
    166 }
    167  
    168 inline int read() {
    169     static int x;
    170     static char ch;
    171     x = 0, ch = getchar();
    172     while (ch < '0' || '9' < ch)
    173         ch = getchar();
    174     while ('0' <= ch && ch <= '9') {
    175         x = x * 10 + ch - '0';
    176         ch = getchar();
    177     }
    178     return x;
    179 }
    View Code

    (p.s. 论编程能力弱的后果。。。写了一下午,调了一晚上QAQQQ)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    pandas之中文分词,词云,情感分析,语义分析3
    pandas之中文分词,词云,情感分析,语义分析2
    pandas之中文分词,词云,情感分析,语义分析1
    大数据学习之-the king of bigdata
    pandas之分组聚合(agg,apply)
    pandas之表的长宽转换
    Pandas数据规整之合并
    Pandas之数据规整
    Pandas数据规整
    IP协议那些事
  • 原文地址:https://www.cnblogs.com/rausen/p/4464328.html
Copyright © 2011-2022 走看看