EntropyIncreaser

BJOI2017 树的难题

Jan 4th, 2018
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. #include <algorithm>
  5.  
  6. #define LOG(FMT...) // fprintf(stderr, "[LOG]"FMT)
  7.  
  8. using namespace std;
  9.  
  10. typedef long long ll;
  11.  
  12. struct node {
  13.     int l, r;
  14.     ll d;
  15.     bool flag;
  16.     node *ls, *rs;
  17.  
  18.     void push_down();
  19.     ll get_d() const;
  20.     ll query(int l, int r);
  21. };
  22.  
  23. struct edge {
  24.     int v, w;
  25.     edge* next;
  26. };
  27.  
  28. const int N = 200010;
  29. const ll INF = 1LL << 50;
  30.  
  31. int n, m, bl, br, ql, qr, ocnt;
  32. ll ans = -INF;
  33. node *seg1, *seg2;
  34. bool vis[N], cut[N];
  35. int c[N], q[N], sum[N], mex[N], ord[N], dep[N], w[N];
  36. ll sc[N];
  37. pair<int, int> son[N];
  38. edge* g[N];
  39.  
  40. void add_edge(int u, int v, int w);
  41. void dfs_order(int u);
  42. void change(node* p, int x, ll d);
  43. void bfs(int u);
  44. node* build(int l, int r);
  45.  
  46. int main() {
  47.     scanf("%d%d%d%d", &n, &m, &bl, &br);
  48.     for (int i = 1; i <= m; ++i)
  49.         scanf("%d", &c[i]);
  50.     for (int rep = 1; rep < n; ++rep) {
  51.         int u, v, w;
  52.         scanf("%d%d%d", &u, &v, &w);
  53.         add_edge(u, v, w);
  54.         add_edge(v, u, w);
  55.     }
  56.     dfs_order(1);
  57.     seg1 = build(1, n);
  58.     seg2 = build(1, n);
  59.     memset(cut, 0, sizeof(cut));
  60.     for (int i = 1; i <= n; ++i) {
  61.         int u = ord[i], scnt = 0;
  62.         LOG("%d\n", u);
  63.         cut[u] = true;
  64.         seg1->flag = true;
  65.         seg2->flag = true;
  66.         for (edge* p = g[u]; p; p = p->next)
  67.             if (!cut[p->v]) {
  68.                 w[p->v] = p->w;
  69.                 sc[p->v] = c[p->w];
  70.                 LOG("->%d %d %d\n", p->v, p->w, c[p->w]);
  71.                 son[++scnt] = make_pair(p->w, p->v);
  72.             }
  73.         sort(son + 1, son + scnt + 1);
  74.         for (int i = 1; i <= scnt; ++i) {
  75.             int u = son[i].second;
  76.             dep[u] = 1;
  77.             bfs(u);
  78.             for (int j = 0; j < qr; ++j) {
  79.                 int v = q[j];
  80.                 LOG("SCORE %d: %lld\n", v, sc[v]);
  81.                 if (dep[v] > br)
  82.                     break;
  83.                 if (dep[v] >= bl)
  84.                     ans = max(ans, sc[v]);
  85.                 if (dep[v] < br) {
  86.                     int l = max(bl - dep[v], 1), r = br - dep[v];
  87.                     ans = max(ans, sc[v] + max(seg1->query(l, r), seg2->query(l, r)));
  88.                 }
  89.                 for (edge* p = g[v]; p; p = p->next)
  90.                     if (!cut[p->v] && dep[v] < dep[p->v]) {
  91.                         w[p->v] = p->w;
  92.                         sc[p->v] = sc[v] + c[p->w];
  93.                         if (w[v] == p->w)
  94.                             sc[p->v] -= c[p->w];
  95.                     }
  96.             }
  97.             for (int j = 0; j < qr; ++j)
  98.                 change(seg2, dep[q[j]], sc[q[j]] - c[w[u]]);
  99.             if (son[i].first != son[i + 1].first) {
  100.                 for (int j = i; son[i].first == son[j].first; --j) {
  101.                     bfs(son[j].second);
  102.                     for (int k = 0; k < qr; ++k)
  103.                         change(seg1, dep[q[k]], sc[q[k]]);
  104.                 }
  105.                 seg2->flag = true;
  106.             }
  107.         }
  108.     }
  109.     printf("%lld\n", ans);
  110.     return 0;
  111. }
  112.  
  113. void bfs(int u) {
  114.     ql = 0;
  115.     qr = 1;
  116.     q[0] = u;
  117.     while (ql < qr) {
  118.         u = q[ql++];
  119.         vis[u] = true;
  120.         for (edge* p = g[u]; p; p = p->next)
  121.             if (!vis[p->v] && !cut[p->v]) {
  122.                 dep[p->v] = dep[u] + 1;
  123.                 q[qr++] = p->v;
  124.             }
  125.     }
  126.     for (int i = 0; i < qr; ++i)
  127.         vis[q[i]] = false;
  128. }
  129.  
  130. node* build(int l, int r) {
  131.     static node pool[N * 4];
  132.     static node* top = pool;
  133.     node* p = top;
  134.     ++top;
  135.     p->l = l;
  136.     p->r = r;
  137.     if (l == r)
  138.         return p;
  139.     int mid = (l + r) / 2;
  140.     p->ls = build(l, mid);
  141.     p->rs = build(mid + 1, r);
  142.     return p;
  143. }
  144.  
  145. void change(node* p, int x, ll d) {
  146.     LOG("CHANGEING %lld\n", d);
  147.     while (p->l != p->r) {
  148.         p->push_down();
  149.         p->d = max(p->d, d);
  150.         if (x <= p->ls->r)
  151.             p = p->ls;
  152.         else
  153.             p = p->rs;
  154.     }
  155.     p->push_down();
  156.     p->d = max(p->d, d);
  157. }
  158.  
  159. void node::push_down() {
  160.     if (flag) {
  161.         flag = false;
  162.         d = -INF;
  163.         if (ls) {
  164.             ls->flag = true;
  165.             rs->flag = true;
  166.         }
  167.     }
  168. }
  169.  
  170. ll node::get_d() const {
  171.     if (flag)
  172.         return -INF;
  173.     return d;
  174. }
  175.  
  176. ll node::query(int l, int r) {
  177.     if (this->l == l && this->r == r)
  178.         return get_d();
  179.     push_down();
  180.     if (r <= ls->r)
  181.         return ls->query(l, r);
  182.     if (l >= rs->l)
  183.         return rs->query(l, r);
  184.     return max(ls->query(l, ls->r), rs->query(rs->l, r));
  185. }
  186.  
  187. void add_edge(int u, int v, int w) {
  188.     static edge pool[N * 2];
  189.     static edge* p = pool;
  190.     p->v = v;
  191.     p->w = w;
  192.     p->next = g[u];
  193.     g[u] = p;
  194.     ++p;
  195. }
  196.  
  197. void dfs_order(int u) {
  198.     bfs(u);
  199.     int myn = 1 << 20;
  200.     for (int i = qr - 1; i >= 0; --i) {
  201.         int v = q[i];
  202.         sum[v] = 1;
  203.         mex[v] = 0;
  204.         for (edge* p = g[v]; p; p = p->next)
  205.             if (dep[v] < dep[p->v] && !cut[p->v]) {
  206.                 sum[v] += sum[p->v];
  207.                 mex[v] = max(mex[v], sum[p->v]);
  208.             }
  209.         mex[v] = max(mex[v], qr - sum[v]);
  210.         if (mex[v] < myn) {
  211.             myn = mex[v];
  212.             u = v;
  213.         }
  214.     }
  215.     cut[u] = true;
  216.     ord[++ocnt] = u;
  217.     for (edge* p = g[u]; p; p = p->next)
  218.         if (!cut[p->v])
  219.             dfs_order(p->v);
  220. }
Advertisement
Add Comment
Please, Sign In to add comment