Dang_Quan_10_Tin

VODONCAY (VOI 2016)

Dec 10th, 2020 (edited)
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.66 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #define task "VODONCAY"
  4. using namespace std;
  5. using ll = long long;
  6. using ld = long double;
  7.  
  8. template <class T>
  9. void read(T &x)
  10. {
  11.     x = 0;
  12.     register int c;
  13.     while ((c = getchar()) && (c > '9' || c < '0'))
  14.         ;
  15.     for (; c >= '0' && c <= '9'; c = getchar())
  16.         x = x * 10 + c - '0';
  17. }
  18.  
  19. const int N = 4e6 + 2;
  20. const int Inf = 1e9 + 7;
  21. int n, par[N][2], parpar[N][2];
  22. int a[N], dp[N][2];
  23. int pre[N], suf[N];
  24.  
  25. template <typename T, typename V>
  26. struct SegmentTree
  27. {
  28.     V st[N * 4];
  29.     T s;
  30.     int n;
  31.     SegmentTree()
  32.     {
  33.     }
  34.     void fill(const V &v)
  35.     {
  36.         fill_n(st, N * 4, v);
  37.     }
  38.     void Update(int id, int l, int r, const int &a, const V &v)
  39.     {
  40.         if (l > a || r < a)
  41.             return;
  42.         if (l == r && r == a)
  43.         {
  44.             st[id] = s.compare(st[id], v);
  45.             return;
  46.         }
  47.         Update(id << 1, l, (l + r) / 2, a, v);
  48.         Update(id << 1 | 1, (l + r) / 2 + 1, r, a, v);
  49.         st[id] = s.compare(st[id << 1], st[id << 1 | 1]);
  50.     }
  51.     void Update(int l, const V &v)
  52.     {
  53.         Update(1, 1, n, l, v);
  54.     }
  55.     V Get(int id, int l, int r, const int &a, const int &b)
  56.     {
  57.         if (l > b || r < a)
  58.             return s.top;
  59.         if (l >= a && r <= b)
  60.             return st[id];
  61.         return s.compare(Get(id << 1, l, (l + r) / 2, a, b),
  62.                          Get(id << 1 | 1, (l + r) / 2 + 1, r, a, b));
  63.     }
  64.     V Get(int l, int r)
  65.     {
  66.         return Get(1, 1, n, l, r);
  67.     }
  68. };
  69. struct Pair
  70. {
  71.     int x, y, z;
  72.     Pair(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}
  73.     bool operator<(const Pair &a) const
  74.     {
  75.         return x < a.x;
  76.     }
  77. };
  78. struct mins
  79. {
  80.     int top = Inf;
  81.     int compare(const int &a, const int &b)
  82.     {
  83.         return a < b ? a : b;
  84.     }
  85. };
  86. struct maxs
  87. {
  88.     int top = -Inf;
  89.     int compare(const int &a, const int &b)
  90.     {
  91.         return a > b ? a : b;
  92.     }
  93. };
  94. struct minpair
  95. {
  96.     Pair top = Pair(Inf, 0, 0);
  97.     Pair compare(const Pair &a, const Pair &b)
  98.     {
  99.         return a < b ? a : b;
  100.     }
  101. };
  102.  
  103. SegmentTree<mins, int> fpre;
  104. SegmentTree<maxs, int> fsuf;
  105. SegmentTree<minpair, Pair> f;
  106.  
  107. void Read()
  108. {
  109.     cin >> n;
  110.     for (int i = 1; i <= n; ++i)
  111.         cin >> a[i];
  112. }
  113.  
  114. void Prepare()
  115. {
  116.     fsuf.n = fpre.n = n;
  117.     fsuf.fill(-Inf);
  118.     fpre.fill(Inf);
  119.     for (int i = 1; i <= n; ++i)
  120.     {
  121.         pre[i] = i;
  122.         int j = max(1, i - a[i] + 1);
  123.         if (j < i)
  124.             pre[i] = fpre.Get(j, i - 1);
  125.         fpre.Update(i, pre[i]);
  126.     }
  127.     for (int i = n; i; --i)
  128.     {
  129.         suf[i] = i;
  130.         int j = min(n, i + a[i] - 1);
  131.         if (j > i)
  132.             suf[i] = fsuf.Get(i + 1, j);
  133.         fsuf.Update(i, suf[i]);
  134.     }
  135.     /*
  136.     for (int i = 1; i <= n; ++i)
  137.         cout << pre[i] << " ";
  138.     cout << "\n";
  139.     for (int i = 1; i <= n; ++i)
  140.         cout << suf[i] << " ";
  141.     cout << "\n";*/
  142. }
  143.  
  144. void Trace(int i, int j)
  145. {
  146.     if (par[i][j] != 0)
  147.         Trace(par[i][j], parpar[i][j]);
  148.     cout << (j ? 1 : -1) * i << " ";
  149. }
  150.  
  151. void Solve()
  152. {
  153.     f.n = n;
  154.     f.fill(f.s.top);
  155.     for (int i = 1; i <= n; ++i)
  156.     {
  157.         int x, y, z, t;
  158.         /// 0 = [pre[i], i]
  159.         /// 1 = [i, suf[i]]
  160.         x = pre[i];
  161.         y = i;
  162.         z = i;
  163.         t = suf[i];
  164.         if (x == 1)
  165.         {
  166.             dp[i][0] = 1;
  167.             if (z == 1)
  168.             {
  169.                 dp[i][1] = 1;
  170.                 f.Update(t, Pair(dp[i][1], i, 1));
  171.             }
  172.             else
  173.             {
  174.                 Pair s = f.Get(z - 1, n);
  175.                 if (s.x != Inf)
  176.                 {
  177.                     dp[i][1] = s.x + 1;
  178.                     par[i][1] = s.y;
  179.                     parpar[i][1] = s.z;
  180.                     f.Update(t, Pair(dp[i][1], i, 1));
  181.                 }
  182.             }
  183.             f.Update(y, Pair(dp[i][0], i, 0));
  184.         }
  185.         else
  186.         {
  187.             Pair s = f.Get(x - 1, n);
  188.             if (s.x != Inf)
  189.             {
  190.                 dp[i][0] = s.x + 1;
  191.                 par[i][0] = s.y;
  192.                 parpar[i][0] = s.z;
  193.                 if (z == 1)
  194.                 {
  195.                     dp[i][1] = 1;
  196.                     f.Update(t, Pair(dp[i][1], i, 1));
  197.                 }
  198.                 else
  199.                 {
  200.                     Pair s = f.Get(z - 1, n);
  201.                     if (s.x != Inf)
  202.                     {
  203.                         dp[i][1] = s.x + 1;
  204.                         par[i][1] = s.y;
  205.                         parpar[i][1] = s.z;
  206.                         f.Update(t, Pair(dp[i][1], i, 1));
  207.                     }
  208.                 }
  209.                 f.Update(y, Pair(dp[i][0], i, 0));
  210.             }
  211.             else
  212.             {
  213.                 if (z == 1)
  214.                 {
  215.                     dp[i][1] = 1;
  216.                     f.Update(t, Pair(dp[i][1], i, 1));
  217.                 }
  218.                 else
  219.                 {
  220.                     Pair s = f.Get(z - 1, n);
  221.                     if (s.x != Inf)
  222.                     {
  223.                         dp[i][1] = s.x + 1;
  224.                         par[i][1] = s.y;
  225.                         parpar[i][1] = s.z;
  226.                         f.Update(t, Pair(dp[i][1], i, 1));
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.     }
  232.     Pair s = f.Get(n, n);
  233.     cout << s.x << "\n";
  234.     Trace(s.y, s.z);
  235. }
  236.  
  237. int32_t main()
  238. {
  239.     ios_base::sync_with_stdio(0);
  240.     cin.tie(0);
  241.     cout.tie(0);
  242.     if (fopen(task ".INP", "r"))
  243.     {
  244.         freopen(task ".INP", "r", stdin);
  245.         freopen(task ".OUT", "w", stdout);
  246.     }
  247.     Read();
  248.     Prepare();
  249.     Solve();
  250. }
  251.  
Add Comment
Please, Sign In to add comment