Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.90 KB | None | 0 0
  1. /*
  2. _ __ U _____ u _ __
  3. |"|/ / \| ___"|/ |"|/ /
  4. | ' / | _|" | ' /
  5. U/| . \\u | |___ U/| . \\u
  6. |_|\_\ |_____| |_|\_\
  7. ,-,>> \\,-.<< >>,-,>> \\,-.
  8. \.) (_/(__) (__)\.) (_/
  9. */
  10. #include <bits/stdc++.h>
  11. using namespace std;
  12.  
  13. typedef long long ll;
  14. typedef long double ld;
  15. typedef unsigned long long ull;
  16. typedef vector<int> vi;
  17. typedef pair<int, int> pii;
  18. typedef pair<long long, long long> pll;
  19. #define zhfs main
  20. #define mp(a, b) make_pair(a, b)
  21. #define fi first
  22. #define se second
  23. #define re return
  24. #define forn(i, n) for (int i = 1; i <= n; i++)
  25. struct segmentTree
  26. {
  27. vector<ull> t, m;
  28. segmentTree(int n)
  29. {
  30. t.resize(4 * n + 7);
  31. m.resize(4 * n + 7, (ull)-1);
  32. }
  33. void push(int v)
  34. {
  35. if (m[v] == (ull)-1) re;
  36. m[v + v] = m[v];
  37. m[v + v + 1] = m[v];
  38. m[v] = (ull)-1;
  39. }
  40. ull getv(int v, int tl, int tr)
  41. {
  42. if (m[v] == (ull)-1) re t[v];
  43. re m[v] * (tr - tl + 1);
  44. }
  45. void draw(int v, int tl, int tr, int l, int r, int x)
  46. {
  47. if (r < tl || l > tr) re;
  48. if (tl >= l && tr <= r)
  49. {
  50. m[v] = x;
  51. re;
  52. }
  53. push(v);
  54. int tm = (tl + tr) >> 1;
  55. draw(v + v, tl, tm, l, r, x);
  56. draw(v + v + 1, tm + 1, tr, l, r, x);
  57. t[v] = getv(v + v, tl, tm) + getv(v + v + 1, tm + 1, tr);
  58. }
  59. ull getSum(int v, int tl, int tr, int l, int r)
  60. {
  61. if (r < tl || l > tr) re 0ULL;
  62. if (tl >= l && tr <= r) re getv(v, tl, tr);
  63. push(v);
  64. int tm = (tl + tr) >> 1;
  65. ll res = getSum(v + v, tl, tm, l, r) + getSum(v + v + 1, tm + 1, tr, l, r);
  66. t[v] = getv(v + v, tl, tm) + getv(v + v + 1, tm + 1, tr);
  67. re res;
  68. }
  69. };
  70. const int MAXN = 200 * 1000 + 7;
  71. ull a[MAXN];
  72. void printTree(segmentTree &st, int n)
  73. {
  74. for (int i = 1; i <= n; i++)
  75. {
  76. printf("%llu ", st.getSum(1, 1, n, i, i));
  77. }
  78. printf("\n");
  79. }
  80. int zhfs()
  81. {
  82. #ifdef LOCAL
  83. freopen("input.txt", "r", stdin);
  84. #endif
  85. int n;
  86. scanf("%d", &n);
  87. for (int i = 1; i <= n; i++)
  88. {
  89. scanf("%llu", &a[i]);
  90. }
  91. vector<pair<int, ull> > minStack, maxStack;
  92. minStack.push_back(make_pair(0, 0));
  93. maxStack.push_back(make_pair(0, MAXN));
  94. segmentTree minTree(n + 1), maxTree(n + 1);
  95. ull sumMin = 0, sumMax = 0, sumMul = 0, res = 0;
  96. for (int i = 1; i <= n; i++)
  97. {
  98. while (minStack.back().second > a[i])
  99. {
  100. int sz = (int)minStack.size();
  101. int l = minStack[sz - 2].first + 1, r = minStack[sz - 1].first;
  102. sumMin -= minStack[sz - 1].se * minStack[sz - 1].se * (r - l + 1);
  103. sumMul += 2ULL * maxTree.getSum(1, 1, n, l, r) * minStack[sz - 1].se;
  104. minTree.draw(1, 1, n, l, r, 0);
  105. minStack.pop_back();
  106. }
  107. while (maxStack.back().second < a[i])
  108. {
  109. int sz = (int)maxStack.size();
  110. int l = maxStack[sz - 2].first + 1, r = maxStack[sz - 1].first;
  111. sumMax -= maxStack[sz - 1].se * maxStack[sz - 1].se * (r - l + 1);
  112. sumMul += 2ULL * minTree.getSum(1, 1, n, l, r) * maxStack[sz - 1].se;
  113. maxTree.draw(1, 1, n, l, r, 0);
  114. maxStack.pop_back();
  115. }
  116. // printf("AFTER POP:\n");
  117. // printf("MINTREE: ");
  118. // printTree(minTree, n);
  119. // printf("MAXTREE: ");
  120. // printTree(maxTree, n);
  121. // printf("sumMin = %lld, sumMax = %lld, sumMul = %lld\n", (ll)sumMin, (ll)sumMax, (ll)sumMul);
  122. sumMin += a[i] * a[i] * (i - minStack.back().fi);
  123. sumMax += a[i] * a[i] * (i - maxStack.back().fi);
  124. sumMul -= 2ULL * a[i] * maxTree.getSum(1, 1, n, minStack.back().fi + 1, i);
  125. minTree.draw(1, 1, n, minStack.back().fi + 1, i, a[i]);
  126. sumMul -= 2ULL * a[i] * minTree.getSum(1, 1, n, maxStack.back().fi + 1, i);
  127. maxTree.draw(1, 1, n, maxStack.back().fi + 1, i, a[i]);
  128. res += sumMin;
  129. res += sumMax;
  130. res += sumMul;
  131. minStack.push_back(make_pair(i, a[i]));
  132. maxStack.push_back(make_pair(i, a[i]));
  133. // printf("AFTER PUSH:\n");
  134. // printf("MINTREE: ");
  135. // printTree(minTree, n);
  136. // printf("MAXTREE: ");
  137. // printTree(maxTree, n);
  138. // printf("sumMin = %lld, sumMax = %lld, sumMul = %lld\n", (ll)sumMin, (ll)sumMax, (ll)sumMul);
  139.  
  140. }
  141. printf("%llu\n", res);
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement