Advertisement
a53

sortall

a53
Oct 30th, 2018
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.46 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <fstream>
  4. #include <vector>
  5. using namespace std;
  6.  
  7. constexpr int mod = 1e9 + 7;
  8. using ll = long long;
  9.  
  10. long long brut(vector<int> v){
  11. long long rez = 0;
  12. for(int i = 0; i < v.size(); ++i){
  13. for(int j = i+1; j <= v.size(); ++j){
  14. vector<int> vv(begin(v) + i, begin(v) + j);
  15. sort(begin(vv), end(vv));
  16. vv.erase(unique(begin(vv), end(vv)), end(vv));
  17. long long delta = 0;
  18. for(int k = 0; k < vv.size(); ++k){
  19. delta += (vv[k] + 1) * (k + 1); }
  20. rez += delta; } }
  21. return rez; }
  22.  
  23. class arbint2d{
  24. int n;
  25. vector<vector<int>> buf;
  26. vector<vector<int>> points;
  27. int poz_in_line(int l, int x){
  28. return lower_bound(begin(points[l]), end(points[l]), x) - begin(points[l]); }
  29. int line_sum(int l, int x, int y){
  30. x = poz_in_line(l, x), y = poz_in_line(l, y + 1);
  31. long long rez = 0;
  32. for(x += points[l].size(), y += points[l].size(); x < y; x /= 2, y /= 2){
  33. if(x%2) rez += buf[l][x++];
  34. if(y%2) rez += buf[l][--y]; }
  35. return rez % mod; }
  36. public:
  37. arbint2d(int N, vector<pair<int, int>>& v) : n(N), buf(2*n), points(2*n){
  38. for(auto x : v) points[x.first + n].push_back(x.second);
  39. for(int i = n; i < 2 * n; ++i){
  40. sort(begin(points[i]), end(points[i]));
  41. points[i].erase(unique(begin(points[i]), end(points[i])), end(points[i])); }
  42.  
  43. for(int i = n-1; i; --i){
  44. merge(begin(points[2*i]), end(points[2*i]),
  45. begin(points[2*i+1]), end(points[2*i+1]),
  46. back_inserter(points[i]));
  47. points[i].erase(unique(begin(points[i]), end(points[i])), end(points[i]));
  48. points[i].shrink_to_fit(); }
  49. for(int i = 1; i < 2 * n; ++i)
  50. buf[i].resize(2 * points[i].size()); }
  51. void update(int x, int y, int delta){
  52. delta -= query(x, x, y, y);
  53. delta %= mod;
  54. if(delta < 0) delta += mod;
  55.  
  56. for(x += n; x; x /= 2){
  57. assert(binary_search(begin(points[x]), end(points[x]), y));
  58. for(int y_ = poz_in_line(x, y) + points[x].size(); y_; y_ /= 2){
  59. buf[x][y_] += delta;
  60. buf[x][y_] %= mod; } } }
  61. int query(int st, int dr, int x, int y){
  62. long long rez = 0;
  63. for(st += n, dr += n + 1; st < dr; st /= 2, dr /= 2){
  64. if(st%2) rez += line_sum(st++, x, y);
  65. if(dr%2) rez += line_sum(--dr, x, y); }
  66. return rez % mod; } };
  67.  
  68. vector<int> build_next(vector<int>& v){
  69. vector<int> next(v.size()), tmp(v.size(), v.size());
  70. for(int i = v.size() - 1; i >= 0; --i){
  71. next[i] = abs(tmp[v[i]] - i);
  72. tmp[v[i]] = i; }
  73. return next; }
  74.  
  75. int main(){
  76. srand(time(nullptr));
  77. ifstream f("sortall.in");
  78. ofstream g("sortall.out");
  79. #ifdef TEST
  80. for(int xxx = 0; ; ++xxx){
  81. #endif
  82. int n;
  83. #ifndef TEST
  84. f >> n;
  85. vector<int> s(n);
  86. for(auto& x : s) f >> x, --x;
  87. #endif
  88. #ifdef TEST
  89. n = 100;
  90. vector<int> s(n);
  91. for(auto& x : s) x = rand()%n;
  92. #endif
  93.  
  94. auto next = build_next(s);
  95. reverse(begin(s), end(s));
  96. auto prev = build_next(s);
  97. reverse(begin(s), end(s));
  98. reverse(begin(prev), end(prev));
  99.  
  100. int delta = 0;
  101. vector<int> dst_(n, 1), ddr_(n, n);
  102.  
  103. for(int i = 0; i < n; ++i)
  104. ddr_[s[i]] = min(ddr_[s[i]], i);
  105.  
  106. auto set_dst = [&](int x, int y){ dst_[x] = y - delta; };
  107. auto set_ddr = [&](int x, int y){ ddr_[x] = y + delta; };
  108.  
  109. vector<pair<int, int>> puncte;
  110.  
  111. for(int i = 0; i < n; ++i)
  112. puncte.emplace_back(s[i], i);
  113. for(int i = 0; i < n; ++i)
  114. puncte.emplace_back(i, n);
  115.  
  116. arbint2d a1(n, puncte), a2(n, puncte), a3(n, puncte), b(n, puncte), b_(n, puncte);
  117.  
  118. long long rez = 0;
  119.  
  120. for(int i = 0; i < n; ){
  121. if(i == 0){
  122. for(int j = 0; j < n; ++j){
  123. a1.update(j, ddr_[j], ((ll)dst_[j] * ddr_[j]) % mod);
  124. a2.update(j, ddr_[j], ((ddr_[j] - dst_[j])%mod + mod)%mod);
  125. a3.update(j, ddr_[j], 1);
  126. b.update(j, ddr_[j], dst_[j]);
  127. b_.update(j, ddr_[j], 1); } }
  128. long long here = 0;
  129. here += ((((ll)(s[i] + 1) * (i + 1))%mod) * next[i])%mod;
  130. here += mod - a1.query(0, s[i]-1, i, i + next[i] - 1);
  131. here += mod - ((ll)delta * a2.query(0, s[i]-1, i, i + next[i] - 1))%mod;
  132. here += ((((ll)delta * delta)%mod) * a3.query(0, s[i]-1, i, i + next[i] - 1))%mod;
  133. here -= (long long)next[i] * ((b.query(0, s[i]-1, i + next[i], n) + (long long)delta * b_.query(0, s[i]-1, i + next[i], n))%mod);
  134. here %= mod;
  135.  
  136. rez += (long long)(s[i] + 1) * here;
  137. rez %= mod;
  138.  
  139. a1.update(s[i], i + next[i], 0);
  140. a2.update(s[i], i + next[i], 0);
  141. a3.update(s[i], i + next[i], 0);
  142. b.update(s[i], i + next[i], 0);
  143. b_.update(s[i], i + next[i], 0);
  144.  
  145. set_dst(s[i], 0);
  146. set_ddr(s[i], next[i]);
  147.  
  148. a1.update(s[i], i + next[i], ((long long)dst_[s[i]] * ddr_[s[i]])%mod);
  149. a2.update(s[i], i + next[i], ddr_[s[i]] - dst_[s[i]]);
  150. a3.update(s[i], i + next[i], 1);
  151. b.update(s[i], i + next[i], dst_[s[i]]);
  152. b_.update(s[i], i + next[i], 1);
  153.  
  154. ++i;
  155. delta += 1; }
  156.  
  157. g << rez << endl;
  158. #ifdef TEST
  159. cout << xxx << endl;
  160. assert(rez == brut(s)); }
  161. #endif
  162. return 0; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement