zoukankan      html  css  js  c++  java
  • BZOJ3999 [TJOI2015]旅游

    题面:给定一个有$n$个节点的树,每个点又点权$v_i$,每次选取一条树链$[a, b]$,求出$max(v_i - v_j)$,其中$i, j in [a, b]$且$i$出现在$j$前面,最后树链$[a, b]$上的点点权都加上$v'$

    裸的树链剖分,用线段树维护树链。。。查询的时候要用线段树合并。。。然后就没有然后了。。。

    代码能力捉鸡QAQQQ,而且貌似是C++程序里面跑的最慢的QAQQQ

      1 /**************************************************************
      2     Problem: 3999
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:4268 ms
      7     Memory:17988 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 typedef long long ll;
     15 const int N = 5e4 + 5;
     16 const int inf = 1e9;
     17  
     18 inline int read();
     19  
     20 int n;
     21 int a[N], seq[N], cnt_seq;
     22  
     23 struct edge {
     24     int next, to;
     25     edge() {}
     26     edge(int _n, int _t) : next(_n), to(_t) {}
     27 } e[N << 1];
     28  
     29 int first[N], tot;
     30  
     31 struct tree_node {
     32     int sz, dep, fa, son, v;
     33     int top, pos;
     34 } tr[N];
     35  
     36 struct seg {
     37     seg *ls, *rs, *res;
     38     ll mx, mn, mxl, mxr, tag;
     39      
     40     #define Len (1 << 16)
     41     inline void* operator new(size_t) {
     42         static seg *mempool, *c;
     43         if (mempool == c)
     44             mempool = (c = new seg[Len]) + Len;
     45         return c++;
     46     }
     47     #undef Len
     48     inline seg& operator += (int x) {
     49         mx += x, mn += x, tag += x;
     50     }
     51      
     52     inline seg* rev() {
     53         swap(mxl, mxr);
     54         return this;
     55     }
     56     inline void update(seg *ls, seg *rs) {
     57         mxl = max(max(ls -> mxl, rs -> mxl), ls -> mx - rs -> mn);      
     58         mxr = max(max(ls -> mxr, rs -> mxr), rs -> mx - ls -> mn);
     59         mx = max(ls -> mx, rs -> mx), mn = min(ls -> mn, rs -> mn);
     60     }
     61     inline void push() {
     62         if (tag) {
     63             *ls += tag, *rs += tag;
     64             tag = 0;
     65         }
     66     }
     67      
     68     #define mid (l + r >> 1)
     69     inline void build(int l, int r, int* a) {
     70         res = new()seg;
     71         if (l == r) {
     72             mx = mn = a[l];
     73             return;
     74         }
     75         ls = new()seg(), rs = new()seg;
     76         ls -> build(l, mid, a), rs -> build(mid + 1, r, a);
     77         update(ls, rs);
     78     }
     79      
     80     inline void add(int l, int r, int L, int R, int d) {
     81         if (L <= l && r <= R) {
     82             *this += d;
     83             return;
     84         }
     85         push();
     86         if (L <= mid) ls -> add(l, mid, L, R, d);
     87         if (mid < R) rs -> add(mid + 1, r, L, R, d);
     88         update(ls, rs);
     89     }
     90      
     91     inline seg* query(int l, int r, int L, int R) {
     92         if (L <= l && r <= R) {
     93             *res = *this;
     94             return res;
     95         }
     96         *res = seg(), push();
     97         if (mid >= R) res = ls -> query(l, mid, L, R);
     98         else if (mid < L) res = rs -> query(mid + 1, r, L, R);
     99         else res -> update(ls -> query(l, mid, L, R), rs -> query(mid + 1, r, L, R));
    100         update(ls, rs);
    101         return res;
    102     }
    103     #undef mid
    104 } *T;
    105  
    106 inline void get(seg *t, int f, int a, int b, int v) {
    107     if (!f) t -> update(T -> query(1, n, a, b), t);
    108     else t -> update(t, T -> query(1, n, a, b) -> rev());
    109     T -> add(1, n, a, b, v);
    110 }
    111  
    112 inline void pre(seg *t) {
    113     *t = seg();
    114     t -> mx = t -> mxl = t -> mxr = -inf, t -> mn = inf;
    115 }
    116  
    117 inline void work(int x, int y, int v) {
    118     static seg *left = new()seg, *right = new()seg, *ans = new()seg;
    119     pre(left), pre(right);
    120     while (tr[x].top != tr[y].top) {
    121         if (tr[tr[x].top].dep > tr[tr[y].top].dep)
    122             get(right, 0, tr[tr[x].top].pos, tr[x].pos, v), x = tr[tr[x].top].fa;
    123         else
    124             get(left, 1, tr[tr[y].top].pos, tr[y].pos, v), y = tr[tr[y].top].fa;
    125     }
    126     if (tr[x].dep > tr[y].dep) get(right, 0, tr[y].pos, tr[x].pos, v);
    127     else get(left, 1, tr[x].pos, tr[y].pos, v);
    128     ans -> update(left, right);
    129     printf("%lld
    ", max(ans -> mxl, 0ll));
    130 }
    131  
    132 inline void Add_Edges(int x, int y) {
    133     e[++tot] = edge(first[x], y), first[x] = tot;
    134     e[++tot] = edge(first[y], x), first[y] = tot;
    135 }
    136  
    137 #define y e[x].to
    138 void dfs(int p) {
    139     int x;
    140     tr[p].sz = 1;
    141     for (x = first[p]; x; x = e[x].next)
    142         if (y != tr[p].fa) {
    143             tr[y].fa = p, tr[y].dep = tr[p].dep + 1;
    144             dfs(y);
    145             tr[p].sz += tr[y].sz;
    146             if (!tr[p].son || tr[tr[p].son].sz < tr[y].sz) tr[p].son = y;
    147         }
    148 }
    149  
    150 void DFS(int p) {
    151     int x;
    152     seq[tr[p].pos = ++cnt_seq] = tr[p].v;
    153     if (!tr[p].son) return;
    154     tr[tr[p].son].top = tr[p].top;
    155     DFS(tr[p].son);
    156     for (x = first[p]; x; x = e[x].next)
    157         if (y != tr[p].fa && y != tr[p].son)
    158             tr[y].top = y, DFS(y);
    159 }
    160 #undef y
    161  
    162 int main() {
    163     int i, x, y, z, Q;
    164     n = read();
    165     for (i = 1; i <= n; ++i) tr[i].v = read();
    166     for (i = 1; i < n; ++i)
    167         Add_Edges(read(), read());
    168     dfs(1);
    169     tr[1].top = 1, DFS(1);
    170     T = new()seg;
    171     T -> build(1, n, seq);
    172     for (Q = read(); Q; --Q) {
    173         x = read(), y = read(), z = read();
    174         work(x, y, z);
    175     }
    176     return 0;
    177 }
    178  
    179 inline int read() {
    180     static int x;
    181     static char ch;
    182     x = 0, ch = getchar();
    183     while (ch < '0' || '9' < ch)
    184         ch = getchar();
    185     while ('0' <= ch && ch <= '9') {
    186         x = x * 10 + ch - '0';
    187         ch = getchar();
    188     }
    189     return x;
    190 }
    View Code
  • 相关阅读:
    python种的builtin函数详解第三篇 C
    python中的buildin函数详解(第一篇) C
    python中的formatter的详细用法 C
    python中的builtin函数详解第二篇 C
    python中函数的默认参数陷阱问题 C
    介绍C++11标准的变长参数模板
    猜数字
    父类和子类
    矩形的面积
    水果类
  • 原文地址:https://www.cnblogs.com/rausen/p/4499010.html
Copyright © 2011-2022 走看看