zoukankan      html  css  js  c++  java
  • [ZJOI2008]树的统计

    嘟嘟嘟

    一看就知道,一道树链剖分板子题,原来2008年的ZJOI这么可爱。

    那啥别忘了权值有负数,所以查询最大值的时候ans初始值应该是-INF,别写成0了。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<stack>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 #define enter puts("")
     13 #define space putchar(' ')
     14 #define Mem(a) memset(a, 0, sizeof(a))
     15 typedef long long ll;
     16 typedef double db;
     17 const int INF = 0x3f3f3f3f;
     18 const db eps  =1e-8;
     19 const int maxn = 3e4 + 5;
     20 inline ll read()
     21 {
     22     ll ans = 0;
     23     char ch = getchar(), last = ' ';
     24     while(!isdigit(ch)) {last = ch; ch = getchar();}
     25     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     26     if(last == '-') ans = -ans;
     27     return ans;
     28 }
     29 inline void write(ll x)
     30 {
     31     if(x < 0) putchar('-'), x = -x;
     32     if(x >= 10) write(x / 10);
     33     putchar(x % 10 + '0');
     34 }
     35 
     36 int n, w[maxn];
     37 vector<int> v[maxn];
     38 
     39 bool vis[maxn];
     40 int fa[maxn], deep[maxn], size[maxn], maxson[maxn];
     41 void dfs1(int now)
     42 {
     43     size[now] = vis[now] = 1;
     44     for(int i = 0; i < (int)v[now].size(); ++i)
     45     {
     46         if(!vis[v[now][i]])
     47         {
     48             fa[v[now][i]] = now;
     49             deep[v[now][i]] = deep[now] + 1;
     50             dfs1(v[now][i]);
     51             size[now] += size[v[now][i]];
     52             if(!maxson[now] || size[v[now][i]] > size[maxson[now]]) maxson[now] = v[now][i];
     53         }
     54     }
     55 }
     56 int top[maxn], dfsx[maxn], pos[maxn], cnt = 0;
     57 void dfs2(int now)
     58 {
     59     vis[now] = 1;
     60     dfsx[now] = ++cnt; pos[cnt] = now;
     61     if(maxson[now])
     62     {
     63         top[maxson[now]] = top[now];
     64         dfs2(maxson[now]);
     65     }
     66     for(int i = 0; i < (int)v[now].size(); ++i)
     67     {
     68         if(!vis[v[now][i]] && v[now][i] != maxson[now])
     69         {
     70             top[v[now][i]] = v[now][i];
     71             dfs2(v[now][i]);
     72         }
     73     }
     74 }
     75 
     76 int l[maxn << 2], r[maxn << 2];
     77 ll Max[maxn << 2], sum[maxn << 2];
     78 void pushup(int now)
     79 {
     80     sum[now] = sum[now << 1] + sum[now << 1 | 1];
     81     Max[now] = max(Max[now << 1], Max[now << 1 | 1]);
     82 }
     83 void build(int L, int R, int now)
     84 {
     85     l[now] = L; r[now] = R;
     86     if(L == R) {sum[now] = Max[now] = w[pos[L]]; return;}
     87     int mid = (L + R) >> 1;
     88     build(L, mid, now << 1);
     89     build(mid + 1, R, now << 1 | 1);
     90     pushup(now);
     91 }
     92 void update(int id, int d, int now)
     93 {
     94     if(l[now] == r[now]) {sum[now] = Max[now] = d; return;}
     95     int mid = (l[now]  + r[now]) >> 1;
     96     if(id <= mid) update(id, d, now << 1);
     97     else update(id, d, now << 1 | 1);
     98     pushup(now);
     99 }
    100 ll query(int L, int R, int now, int flag)
    101 {
    102     if(l[now] == L && r[now] == R) return flag ? sum[now] : Max[now]; 
    103     int mid = (l[now] + r[now]) >> 1;
    104     if(R <= mid) return query(L, R, now << 1, flag);
    105     else if(L > mid) return query(L, R, now << 1 | 1, flag);
    106     else 
    107     {
    108         if(flag) return query(L, mid, now << 1, flag) + query(mid + 1, R, now << 1 | 1, flag);
    109         else return max(query(L, mid, now << 1, flag), query(mid + 1, R, now << 1 | 1, flag));
    110     }
    111 }
    112 
    113 ll query2(int x, int y, bool flag)
    114 {
    115     ll ans = flag ? 0 : -INF;
    116     while(top[x] != top[y])
    117     {
    118         if(deep[top[x]] < deep[top[y]]) swap(x, y);
    119         if(flag) ans += query(dfsx[top[x]], dfsx[x], 1, flag);
    120         else ans = max(ans, query(dfsx[top[x]], dfsx[x], 1, flag));
    121         x = fa[top[x]];
    122     }
    123     if(deep[x] < deep[y]) swap(x, y);
    124     if(flag) ans += query(dfsx[y], dfsx[x], 1, flag);
    125     else ans = max(ans, query(dfsx[y], dfsx[x], 1, flag));
    126     return ans;
    127 }
    128 
    129 int main()
    130 {
    131     n = read();
    132     for(int i = 1; i < n; ++i)
    133     {
    134         int x = read(), y = read();
    135         v[x].push_back(y); v[y].push_back(x);
    136     }
    137     for(int i = 1; i <= n; ++i) w[i] = read();
    138     dfs1(1); Mem(vis); dfs2(1);
    139     int q = read();
    140     build(1, cnt, 1);
    141     for(int i = 1; i <= q; ++i)
    142     {
    143         char c[8]; scanf("%s", c);
    144         if(c[0] == 'C')
    145         {
    146             int u = read(), t = read();
    147             update(dfsx[u], t, 1);
    148         }
    149         else if(c[1] == 'M')    //max:0
    150         {
    151             int u = read(), v = read();
    152             write(query2(u, v, 0)); enter;
    153         }
    154         else
    155         {
    156             int u = read(), v = read();
    157             write(query2(u, v, 1)); enter;
    158         }
    159     }
    160     return 0;
    161 }
    View Code
  • 相关阅读:
    C# IP地址字符串和数值转换
    Xstream序列化实体
    异步线程及同步控制
    XML序列化与反序列化(转)
    C# Webserice 代理生成工具(WSDL)
    ASP.NET(C#)图片加文字、图片水印(转)
    异步导致UI句柄增加的解决办法
    终于找到WinForm自定义控件不能拖到IDE设计器容器的办法
    C# PropertyGrid控件应用心得(转载)
    GDI_图片半透明效果示例
  • 原文地址:https://www.cnblogs.com/mrclr/p/9493012.html
Copyright © 2011-2022 走看看