EntropyIncreaser

BJOI2017 喷式水战改

Dec 2nd, 2017
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.99 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. #include <algorithm>
  5.  
  6. #define LOG(FMT...) // fprintf(stderr, FMT)
  7.  
  8. using namespace std;
  9.  
  10. typedef long long ll;
  11.  
  12. struct data {
  13.     ll dp[4][4];
  14.  
  15.     data()
  16.     { memset(dp, 0, sizeof(dp)); }
  17.  
  18.     data(const data& x)
  19.     { memcpy(dp, x.dp, sizeof(dp)); }
  20.  
  21.     data(int a, int b, int c, int x);
  22.  
  23.     data operator+(const data& x) const;
  24. };
  25.  
  26. struct node {
  27.     ll a, b, c, sz, cnt;
  28.     int rnd;
  29.     data d, sum;
  30.     node *ls, *rs;
  31. };
  32.  
  33. const int N = 100010;
  34.  
  35. int n;
  36. node* root;
  37.  
  38. int fast_rand();
  39. ll get_cnt(node* p);
  40. node* create(int a, int b, int c, int x);
  41. void update(node* p);
  42. void insert(node*& p, node* q, ll x);
  43. void zig(node*& p);
  44. void zag(node*& p);
  45. void order(node* p);
  46.  
  47. int main() {
  48.     int a, b, c, x;
  49.     ll p;
  50.     ll lste = 0, cure;
  51.     scanf("%d", &n);
  52.     while (n--) {
  53.         scanf("%lld%d%d%d%d", &p, &a, &b, &c, &x);
  54.         insert(root, create(a, b, c, x), p);
  55.         cure = root->sum.dp[0][3];
  56.         printf("%lld\n", cure - lste);
  57.         lste = cure;
  58.         LOG("\n");
  59.     }
  60.     return 0;
  61. }
  62.  
  63. void order(node* p) {
  64.     if (!p)
  65.         return;
  66.     order(p->ls);
  67.     LOG(" %d", p->sz);
  68.     order(p->rs);
  69. }
  70.  
  71. inline int fast_rand() {
  72.     static int x = 19260817, y = x << 4, z = x >> 2, t;
  73.     t = x ^ y ^ z;
  74.     x ^= y << 2;
  75.     x ^= z >> 4;
  76.     z = y;
  77.     y = x;
  78.     x = t;
  79.     return t;
  80. }
  81.  
  82. inline ll get_cnt(node* p)
  83. { return p ? p->cnt : 0; }
  84.  
  85. inline void update(node* p) {
  86.     p->cnt = p->sz + get_cnt(p->ls) + get_cnt(p->rs);
  87.     p->sum = p->d;
  88.     if (p->ls)
  89.         p->sum = p->ls->sum + p->sum;
  90.     if (p->rs)
  91.         p->sum = p->sum + p->rs->sum;
  92. }
  93.  
  94. inline node* create(int a, int b, int c, int x) {
  95.     static node pool[N << 1];
  96.     static node* p = pool;
  97.     ++p;
  98.     p->d = data(a, b, c, x);
  99.     p->a = a;
  100.     p->b = b;
  101.     p->c = c;
  102.     p->sz = x;
  103.     p->sum = p->d;
  104.     p->rnd = fast_rand();
  105.     p->cnt = x;
  106.     return p;
  107. }
  108.  
  109. inline void zig(node*& p) {
  110.     node* son = p->ls;
  111.     p->ls = son->rs;
  112.     son->rs = p;
  113.     update(p);
  114.     p = son;
  115.     update(p);
  116. }
  117.  
  118. inline void zag(node*& p) {
  119.     node* son = p->rs;
  120.     p->rs = son->ls;
  121.     son->ls = p;
  122.     update(p);
  123.     p = son;
  124.     update(p);
  125. }
  126.  
  127. void insert(node*& p, node* q, ll x) {
  128.     if (!p) {
  129.         LOG("%d\n", x);
  130.         p = q;
  131.         return;
  132.     }
  133.     if (x <= get_cnt(p->ls)) {
  134.         insert(p->ls, q, x);
  135.         update(p);
  136.         if (p->rnd > p->ls->rnd)
  137.             zig(p);
  138.         return;
  139.     }
  140.     x -= get_cnt(p->ls);
  141.     if (x >= p->sz) {
  142.         insert(p->rs, q, x - p->sz);
  143.         update(p);
  144.         if (p->rnd > p->rs->rnd)
  145.             zag(p);
  146.         return;
  147.     }
  148.     p->d = data(p->a, p->b, p->c, p->sz - x);
  149.     node* r = create(p->a, p->b, p->c, x);
  150.     p->sz -= x;
  151.     r->ls = p->ls;
  152.     p->ls = r;
  153.     r->rs = q;
  154.     update(r);
  155.     update(p);
  156. }
  157.  
  158. data::data(int a, int b, int c, int x) {
  159.     dp[0][0] = dp[3][3] = (ll)a * x;
  160.     dp[1][1] = (ll)b * x;
  161.     dp[2][2] = (ll)c * x;
  162.     for (int i = 0; i < 4; ++i)
  163.         for (int j = i + 1; j < 4; ++j)
  164.             dp[i][j] = max(dp[i][j - 1], dp[j][j]);
  165. }
  166.  
  167. data data::operator+(const data& x) const {
  168.     data ret;
  169.     for (int i = 0; i < 4; ++i)
  170.         for (int j = i; j < 4; ++j)
  171.             for (int k = i; k <= j; ++k)
  172.                 ret.dp[i][j] = max(ret.dp[i][j], dp[i][k] + x.dp[k][j]);
  173.     return ret;
  174. }
Advertisement
Add Comment
Please, Sign In to add comment