• BZOJ3531 [Sdoi2014]旅行


    首先我们链剖一下。。。

    然后建立n棵线段树,分别维护n个不同颜色的信息。

    于是MLE 233

    其实发现线段树并不会开满的,于是只要动态开点即可。

    做完了。

      1 /**************************************************************
      2     Problem: 3531
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:7692 ms
      7     Memory:170268 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 const int N = 100005;
     15 const int M = 10000005;
     16  
     17 struct edge {
     18     int next, to;
     19     edge() {}
     20     edge(int _n, int _t) : next(_n), to(_t) {}
     21 } e[N << 1];
     22  
     23 struct tree_node {
     24     int fa, son;
     25     int dep, sz, top, w;
     26 } tr[N];
     27 int cnt_tree;
     28  
     29 struct segment_node {
     30     int mx, sum, lson, rson;
     31 } seg[M];
     32 int cnt_seg;
     33  
     34 int n;
     35 int first[N], tot;
     36 int root[N], c[N], w[N];
     37  
     38 inline int read() {
     39     int x = 0;
     40     char ch = getchar();
     41     while (ch < '0' || '9' < ch)
     42         ch = getchar();
     43     while ('0' <= ch && ch <= '9') {
     44         x = x * 10 + ch - '0';
     45         ch = getchar();
     46     }
     47     return x;
     48 }
     49  
     50 inline void Add_Edges(int x, int y) {
     51     e[++tot] = edge(first[x], y), first[x] = tot;
     52     e[++tot] = edge(first[y], x), first[y] = tot;
     53 }
     54  
     55 void dfs(int p) {
     56     int i, x, y;
     57     tr[p].sz = 1;
     58     for (x = first[p]; x; x = e[x].next)
     59         if (!tr[y = e[x].to].fa) {
     60             tr[y].dep = tr[p].dep + 1;
     61             tr[y].fa = p;
     62             dfs(y);
     63             tr[p].sz += tr[y].sz;
     64             if (!tr[p].son || tr[tr[p].son].sz < tr[y].sz)
     65                 tr[p].son = y;
     66         }
     67 }
     68  
     69 void Dfs(int p) {
     70     tr[p].w = ++cnt_tree;
     71     if (!tr[p].son) return;
     72     tr[tr[p].son].top = tr[p].top;
     73     Dfs(tr[p].son);
     74     int x, y;
     75     for (x = first[p]; x; x = e[x].next)
     76         if (tr[y = e[x].to].fa == p && y != tr[p].son) {
     77             tr[y].top = y;
     78             Dfs(y);
     79         }
     80 }
     81  
     82  
     83 #define mid (l + r >> 1)
     84 inline void refresh(int p) {
     85     seg[p].mx = max(seg[seg[p].lson].mx, seg[seg[p].rson].mx);
     86     seg[p].sum = seg[seg[p].lson].sum + seg[seg[p].rson].sum;
     87 }
     88  
     89 void update(int &p, int l, int r, int pos, int num) {
     90     if (!p) p = ++cnt_seg;
     91     if (l == r) {
     92         seg[p].mx = seg[p].sum = num;
     93         return;
     94     }
     95     if (pos <= mid) update(seg[p].lson, l, mid, pos, num);
     96     else update(seg[p].rson, mid + 1, r, pos, num);
     97     refresh(p);
     98 }
     99  
    100 int query_mx(int p, int l, int r, int L, int R) {
    101     if (!p) return 0;
    102     if (L <= l && r <= R) return seg[p].mx;
    103     if (R <= mid) return query_mx(seg[p].lson, l, mid, L, R);
    104     else if (mid < L) return query_mx(seg[p].rson, mid + 1, r, L, R);
    105     else return max(query_mx(seg[p].lson, l, mid, L, R), 
    106                 query_mx(seg[p].rson, mid + 1, r, L, R));
    107 }
    108  
    109 int query_sum(int p, int l, int r, int L, int R) {
    110     if (!p) return 0;
    111     if (L <= l && r <= R) return seg[p].sum;
    112     if (R <= mid) return query_sum(seg[p].lson, l, mid, L, R);
    113     else if (mid < L) return query_sum(seg[p].rson, mid + 1, r, L, R);
    114     else return query_sum(seg[p].lson, l, mid, L, R) + 
    115                 query_sum(seg[p].rson, mid + 1, r, L, R);
    116 }
    117  
    118  
    119 int work_sum(int x, int y) {
    120     int C = c[x], res = 0;
    121     while (tr[x].top != tr[y].top) {
    122         if (tr[tr[x].top].dep < tr[tr[y].top].dep)
    123             swap(x, y);
    124         res += query_sum(root[C], 1, n, tr[tr[x].top].w, tr[x].w);
    125         x = tr[tr[x].top].fa;
    126     }
    127     if (tr[x].dep < tr[y].dep)
    128         swap(x, y);
    129     res += query_sum(root[C], 1, n, tr[y].w, tr[x].w);
    130     return res;
    131 }
    132  
    133 int work_mx(int x, int y) {
    134     int C = c[x], res = 0;
    135     while (tr[x].top != tr[y].top) {
    136         if (tr[tr[x].top].dep < tr[tr[y].top].dep)
    137             swap(x, y);
    138         res = max(res, query_mx(root[C], 1, n, tr[tr[x].top].w, tr[x].w));
    139         x = tr[tr[x].top].fa;
    140     }
    141     if (tr[x].dep < tr[y].dep)
    142         swap(x, y);
    143     res = max(res, query_mx(root[C], 1, n, tr[y].w, tr[x].w));
    144     return res;
    145 }
    146  
    147  
    148 void build() {
    149     int i;
    150     for (i = 1; i <= n; ++i)
    151         w[i] = read(), c[i] = read();
    152     for (i = 1; i < n; ++i)
    153         Add_Edges(read(), read());
    154     tr[1].fa = -1;
    155     dfs(1);
    156     Dfs(1);
    157     for (i = 1; i <= n; ++i)
    158         update(root[c[i]], 1, n, tr[i].w, w[i]);
    159 }
    160  
    161 void work() {
    162     int x, y;
    163     char st[10];
    164     scanf("%s", st);
    165     x = read(), y = read();
    166     if (st[0] == 'C')
    167         if (st[1] == 'C') {
    168             update(root[c[x]], 1, n, tr[x].w, 0);
    169             update(root[c[x] = y], 1, n, tr[x].w, w[x]);
    170         }
    171         else update(root[c[x]], 1, n, tr[x].w, w[x] = y);
    172     else
    173         if (st[1] == 'S') printf("%d
    ", work_sum(x, y));
    174         else printf("%d
    ", work_mx(x, y));
    175 }
    176  
    177 int main() {
    178     int Q;
    179     n = read(), Q = read();
    180     build();
    181     while (Q--)
    182         work();
    183     return 0;
    184 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    HTTP是什么?,GET与POST区别?
    python3学习笔记二(注释、缩进)
    python3学习笔记一(标识符、关键字)
    python之冒泡排序(一)
    Jenkins 持续集成配置,代码库Perforce
    新增模块的测试用例设计
    Perforce 常用操作(转)
    Python 异常处理——处理默认错误类型以外错误
    测试如何与开发沟通
    selenium webdrive 默认打开浏览器设置
  • 原文地址:https://www.cnblogs.com/rausen/p/4136025.html
Copyright © 2020-2023  润新知