EntropyIncreaser

[PA 2017] Banany

Feb 17th, 2018
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.98 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. #include <algorithm>
  5.  
  6. #define LOG(FMT...) // fprintf(stderr, FMT)
  7.  
  8. typedef long long ll;
  9.  
  10. struct data {
  11.     ll s;
  12.     int id;
  13.  
  14.     data() {}
  15.  
  16.     data(ll s, int id) : s(s), id(id) {}
  17.  
  18.     bool operator<(const data& x) const { return s < x.s || (s == x.s && id > x.id); }
  19.  
  20.     data operator+(ll x) const { return data(s + x, id); }
  21.  
  22.     data operator+=(ll x) { s += x; return *this; }
  23. };
  24.  
  25. struct node {
  26.     data d;
  27.     ll lazy;
  28.     int l, r;
  29.     node *ls, *rs;
  30.  
  31.     void push_down();
  32.     data get_d() const;
  33.     data query(int l, int r);
  34.     void change(int l, int r, ll x);
  35. };
  36.  
  37. struct edge {
  38.     int v;
  39.     ll w;
  40.     edge* next;
  41. };
  42.  
  43. const int N = 100010, LGN = 20;
  44. const ll INF = 1LL << 62;
  45. const data DINF(-INF, 1 << 30);
  46.  
  47. int tm;
  48. bool vis[N], cut[N];
  49. int son[N], minmax[N], maxson[N], rid[N], cnt[N];
  50. ll z[N], dis[N], ox[N];
  51. edge* g[N];
  52. node *xseg[N];
  53. int rt[N][LGN], tlv[N][LGN], trv[N][LGN], prt[N][LGN];
  54. ll pw[N][LGN];
  55.  
  56. void add_edge(int u, int v, ll w);
  57. void divide(int u, int n);
  58. void dfs(int u, int n);
  59. void dfs2(int crt, int u);
  60. node* create(int l, int r);
  61.  
  62. int main() {
  63. //  freopen("test.out", "w", stdout);
  64. //  freopen("test.err", "w", stderr);
  65.     int n, q, s = 1;
  66.     scanf("%d%d", &n, &q);
  67.     for (int i = 1; i <= n; ++i)
  68.         scanf("%lld", &z[i]);
  69.     for (int rep = 1; rep < n; ++rep) {
  70.         int u, v;
  71.         ll w;
  72.         scanf("%d%d%lld", &u, &v, &w);
  73.         add_edge(u, v, w);
  74.         add_edge(v, u, w);
  75.     }
  76.     divide(1, n);
  77.     while (q--) {
  78.         int opt, u;
  79.         scanf("%d%d", &opt, &u);
  80.         if (opt == 1) {
  81.             ll zi, delt;
  82.             scanf("%lld", &zi);
  83.             delt = zi - z[u];
  84.             z[u] = zi;
  85.             for (int i = 0; i < cnt[u]; ++i) {
  86.                 LOG("CHANGE %d\n", tlv[u][i]);
  87.                 xseg[rt[u][i]]->change(tlv[u][i], tlv[u][i], delt);
  88.             }
  89.         } else {
  90.             int v;
  91.             ll w;
  92.             scanf("%d%lld", &v, &w);
  93.             for (int i = 0; i < cnt[u]; ++i)
  94.                 if (prt[u][i] == v) {
  95.                     ll delt = w - pw[u][i];
  96.                     pw[u][i] = w;
  97.                     xseg[rt[u][i]]->change(tlv[u][i], trv[u][i], -delt);
  98.                 }
  99.             std::swap(u, v);
  100.             for (int i = 0; i < cnt[u]; ++i)
  101.                 if (prt[u][i] == v) {
  102.                     ll delt = w - pw[u][i];
  103.                     pw[u][i] = w;
  104.                     xseg[rt[u][i]]->change(tlv[u][i], trv[u][i], -delt);
  105.                 }
  106.         }
  107.         data ans(DINF);
  108.         for (int i = 0; i < cnt[s]; ++i) {
  109.             ans = std::max(ans, std::max(xseg[rt[s][i]]->query(1, tlv[s][i] - 1), xseg[rt[s][i]]->query(tlv[s][i] + 1, xseg[rt[s][i]]->r)) + xseg[rt[s][i]]->query(tlv[s][i], tlv[s][i]).s);
  110.             LOG("%d: %lld\n", ans.id, ans.s - z[s]);
  111.             LOG("%d\n", tlv[s][i]);
  112.         }
  113.         s = ans.id;
  114.         if (q)
  115.             printf("%d ", s);
  116.         else
  117.             printf("%d\n", s);
  118.     }
  119.     for (int i = 1; i <= n; ++i)
  120.         LOG("%d\n", cnt[i]);
  121.     return 0;
  122. }
  123.  
  124. void divide(int u, int n) {
  125.     dfs(u, n);
  126.     u = minmax[u];
  127.     LOG("DIVIDE %d %d %d\n", u, son[u], n);
  128.     tm = 0;
  129.     cut[u] = true;
  130.     dis[u] = 0;
  131.     dfs2(u, u);
  132.     xseg[u] = create(1, n);
  133.     for (edge* p = g[u]; p; p = p->next)
  134.         if (!cut[p->v])
  135.             divide(p->v, son[p->v]);
  136. }
  137.  
  138. void dfs2(int crt, int u) {
  139.     vis[u] = true;
  140.     ++tm;
  141.     int c = cnt[u];
  142.     if (++cnt[u] >= LGN)
  143.         exit(0);
  144.     rt[u][c] = crt;
  145.     tlv[u][c] = tm;
  146.     ox[tm] = z[u] - dis[u];
  147.     rid[tm] = u;
  148.     son[u] = 1;
  149.     for (edge* p = g[u]; p; p = p->next)
  150.         if (!vis[p->v] && !cut[p->v]) {
  151.             dis[p->v] = dis[u] + p->w;
  152.             prt[p->v][c] = u;
  153.             pw[p->v][c] = p->w;
  154.             LOG("%d->%d\n", u, p->v);
  155.             dfs2(crt, p->v);
  156.             son[u] += son[p->v];
  157.         }
  158.     trv[u][c] = tm;
  159.     vis[u] = false;
  160. }
  161.  
  162. void dfs(int u, int n) {
  163.     vis[u] = true;
  164.     son[u] = 1;
  165.     maxson[u] = 0;
  166.     for (edge* p = g[u]; p; p = p->next)
  167.         if (!vis[p->v] && !cut[p->v]) {
  168.             dfs(p->v, n);
  169.             son[u] += son[p->v];
  170.             maxson[u] = std::max(maxson[u], son[p->v]);
  171.         }
  172.     minmax[u] = u;
  173.     for (edge* p = g[u]; p; p = p->next)
  174.         if (!vis[p->v] && !cut[p->v] && std::max(maxson[minmax[u]], n - son[minmax[u]]) > std::max(maxson[minmax[p->v]], n - son[minmax[p->v]]))
  175.             minmax[u] = minmax[p->v];
  176.     vis[u] = false;
  177. }
  178.  
  179. node* create(int l, int r) {
  180.     static node pool[N * LGN * 2];
  181.     static node* top = pool;
  182.     node* p = top;
  183.     ++top;
  184.     p->l = l;
  185.     p->r = r;
  186.     if (l == r) {
  187.         p->d = data(ox[l], rid[l]);
  188.         return p;
  189.     }
  190.     int mid = (l + r) >> 1;
  191.     p->ls = create(l, mid);
  192.     p->rs = create(mid + 1, r);
  193.     p->d = std::max(p->ls->d, p->rs->d);
  194.     return p;
  195. }
  196.  
  197. void add_edge(int u, int v, ll w) {
  198.     static edge pool[N * 2];
  199.     static edge* p = pool;
  200.     p->v = v;
  201.     p->w = w;
  202.     p->next = g[u];
  203.     g[u] = p;
  204.     ++p;
  205. }
  206.  
  207. void node::push_down() {
  208.     if (!lazy)
  209.         return;
  210.     d += lazy;
  211.     ls->lazy += lazy;
  212.     rs->lazy += lazy;
  213.     lazy = 0;
  214. }
  215.  
  216. void node::change(int l, int r, ll x) {
  217.     if (this->l == l && this->r == r) {
  218.         lazy += x;
  219.         return;
  220.     }
  221.     push_down();
  222.     if (r <= ls->r)
  223.         ls->change(l, r, x);
  224.     else if (l >= rs->l)
  225.         rs->change(l, r, x);
  226.     else {
  227.         ls->change(l, ls->r, x);
  228.         rs->change(rs->l, r, x);
  229.     }
  230.     d = std::max(ls->get_d(), rs->get_d());
  231. }
  232.  
  233. data node::query(int l, int r) {
  234.     if (l > r)
  235.         return DINF;
  236.     if (this->l == l && this->r == r)
  237.         return get_d();
  238.     push_down();
  239.     if (r <= ls->r)
  240.         return ls->query(l, r);
  241.     if (l >= rs->l)
  242.         return rs->query(l, r);
  243.     return std::max(ls->query(l, ls->r), rs->query(rs->l, r));
  244. }
  245.  
  246. data node::get_d() const {
  247.     return d + lazy;
  248. }
Advertisement
Add Comment
Please, Sign In to add comment