• bzoj4196 [Noi2015]软件包管理器 树链剖分


    需要按照DFS来init,不能用BFS。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm> 
      5 using namespace std;
      6 const int MAXN = 200005,MAXM = 200005;
      7 int cnt,tot,n,m;
      8 int head[MAXN],fa[MAXN],que[MAXN],dep[MAXN],son[MAXN],top[MAXN],pos[MAXN],idx[MAXN],siz[MAXN],rgt[MAXN];
      9 int to[MAXM],nxt[MAXM];
     10 int lzy[4 * MAXN],data[4 * MAXN]; 
     11 void add(int x,int y)
     12 {
     13     nxt[++cnt] = head[x];
     14     to[cnt] = y;
     15     head[x] = cnt;
     16 }
     17 int dfs1(int x)
     18 {
     19     idx[pos[x] = ++tot] = x;
     20     rgt[x] = tot;
     21     for (int i = head[x];i;i = nxt[i])
     22     {
     23         if (to[i] == fa[x]) continue;
     24         if (to[i] != son[x]) continue; 
     25         top[to[i]] = top[x];
     26         rgt[x] = max(rgt[x],dfs1(to[i]));
     27     }
     28     for (int i = head[x];i;i = nxt[i])
     29     {
     30         if (to[i] == fa[x]) continue;
     31         if (to[i] == son[x]) continue;
     32         top[to[i]] = to[i];
     33         rgt[x] = max(rgt[x],dfs1(to[i])); 
     34     }
     35     return rgt[x];
     36 }
     37 void build(int k,int l,int r)
     38 {
     39     lzy[k] = -1;
     40     if (l == r) return;
     41     int mid = l + r >> 1;
     42     build(k << 1,l,mid);
     43     build(k << 1 | 1,mid + 1,r); 
     44 }
     45 void init()
     46 {
     47     int top = 0;
     48     que[++top] = 1;
     49     dep[1] = 1;
     50     for (int i = top;i <= top;i++)
     51     {
     52         int u = que[i];
     53 //      printf("bfs %d
    ",u); 
     54         siz[u] = 1;
     55         for (int o = head[u];o;o = nxt[o])
     56         {
     57             if (to[o] == fa[u]) continue;
     58             dep[to[o]] = dep[u] + 1;
     59             que[++top] = to[o];
     60         }
     61     }
     62     for (int i = top;i;i--)
     63     {
     64         int u = que[i];
     65         siz[fa[u]] += siz[u]; 
     66         if (siz[u] > siz[son[fa[u]]])
     67         {
     68             son[fa[u]] = u;
     69         }
     70     }
     71     ::top[1] = 1;
     72     dfs1(1);
     73     build(1,1,tot);
     74 }
     75 void push_down(int k,int l,int r)
     76 {
     77     if (lzy[k] < 0) return;
     78     int ch1 = k << 1,ch2 = k << 1 | 1,mid = l + r >> 1;
     79     lzy[ch1] = lzy[ch2] = lzy[k];
     80     data[ch1] = (mid - l + 1) * lzy[k];
     81     data[ch2] = (r - mid) * lzy[k];
     82     lzy[k] = -1;
     83 }
     84 int vec_query(int k,int l,int r,int x,int y,int o)
     85 {
     86     if (x <= l && r <= y)
     87     {
     88         if (o == 0) return (r - l + 1) - data[k];
     89         return data[k];
     90     }
     91     push_down(k,l,r);
     92     int mid = l + r >> 1,res = 0;
     93     if (x <= mid) res += vec_query(k << 1,l,mid,x,y,o);
     94     if (y > mid) res += vec_query(k << 1 | 1,mid + 1,r,x,y,o);
     95     return res;
     96 }
     97 void vec_change(int k,int l,int r,int x,int y,int o)
     98 {
     99     if (x <= l && r <= y)
    100     {
    101         if (o == 0)
    102         {
    103             data[k] = 0;
    104             lzy[k] = 0;
    105             return;
    106         }
    107         data[k] = (r - l + 1);
    108         lzy[k] = 1;
    109         return;
    110     }
    111     push_down(k,l,r);
    112     int mid = l + r >> 1;
    113     if (x <= mid) vec_change(k << 1,l,mid,x,y,o);
    114     if (y > mid) vec_change(k << 1 | 1,mid + 1,r,x,y,o); 
    115     data[k] = data[k << 1] + data[k << 1 | 1];
    116 }
    117 int tree_query(int l,int r,int o)
    118 {
    119     int res = 0;
    120     while (top[l] != top[r])
    121     {
    122         if (dep[top[l]] < dep[top[r]]) swap(l,r);
    123         res += vec_query(1,1,tot,pos[top[l]],pos[l],o);
    124         l = fa[top[l]];
    125     }
    126     if (dep[l] < dep[r]) swap(l,r);
    127     res += vec_query(1,1,tot,pos[r],pos[l],o);
    128     return res;
    129 }
    130 void tree_change(int l,int r,int o)
    131 {
    132     int res = 0;
    133     while (top[l] != top[r])
    134     {
    135         if (dep[top[l]] < dep[top[r]]) swap(l,r);
    136         vec_change(1,1,tot,pos[top[l]],pos[l],o);
    137         l = fa[top[l]];
    138     }
    139     if (dep[l] < dep[r]) swap(l,r);
    140     vec_change(1,1,tot,pos[r],pos[l],o);
    141 }
    142 int area_query(int k,int o)
    143 {
    144     return vec_query(1,1,tot,pos[k],rgt[k],o);
    145 }
    146 void area_change(int k,int o)
    147 {
    148     vec_change(1,1,tot,pos[k],rgt[k],o);
    149 }
    150 int main()
    151 {
    152     scanf("%d",&n);
    153     for (int i = 2;i <= n;i++)
    154     {
    155         scanf("%d",&fa[i]);
    156         fa[i]++;
    157         add(fa[i],i); 
    158     }
    159     init();
    160 //  for (int i = 1;i <= tot;i++) printf("%d ^%d 
    ",i,idx[i]);
    161 //  for (int i = 1;i <= tot;i++) printf("%d *%d 
    ",i,rgt[i]); 
    162 //  for (int i = 1;i <= tot;i++) printf("%d *%d 
    ",i,son[i]);
    163 //  for (int i = 1;i <= tot;i++) printf("%d &%d 
    ",i,top[i]); 
    164 //  for (int i = 2;i <= tot;i++) printf("%d $%d 
    ",i,siz[i]); 
    165     scanf("%d",&m);
    166     for (int i = 1;i <= m;i++)
    167     {
    168         char s[20];
    169         int opt;
    170         scanf("%s%d",s,&opt);
    171         opt++;
    172         if (s[0] == 'i')
    173         {
    174             printf("%d
    ",tree_query(1,opt,0));
    175             tree_change(1,opt,1);
    176         }else
    177         {
    178             printf("%d
    ",area_query(opt,1));
    179             area_change(opt,0);
    180         }
    181     }
    182     return 0;
    183 }
  • 相关阅读:
    温故而知新汇总贴
    温故而知新—heap
    温故而知新--hashtable
    温故而知新-set
    温故而知新——map
    温故而知新----stack
    找工作的时候我们改准备些什么
    js瀑布流布局
    js小游戏---智力游戏
    原生js完成拼图小游戏
  • 原文地址:https://www.cnblogs.com/iat14/p/12217690.html
Copyright © 2020-2023  润新知