Advertisement
erek1e

NOI '10 P2 - Super Piano

May 6th, 2023
802
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.88 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <climits>
  5.  
  6. using namespace std;
  7.  
  8. int const N = 5e5, A = 1e3;
  9.  
  10. // Fenwick Tree:
  11. void update(vector<long long> &fenwick, int index, long long value) {
  12.     while (index < (int)fenwick.size()) {
  13.         fenwick[index] += value;
  14.         index += index & -index;
  15.     }
  16. }
  17. long long getSum(const vector<long long> &fenwick, int index) {
  18.     long long sum = 0;
  19.     while (index) {
  20.         sum += fenwick[index];
  21.         index -= index & -index;
  22.     }
  23.     return sum;
  24. }
  25.  
  26. int main() {
  27.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  28.     int n, k, L, R;
  29.     cin >> n >> k >> L >> R;
  30.     vector<int> a(1+n), p(1+n);
  31.     for (int i = 1; i <= n; ++i) {
  32.         cin >> a[i], p[i] = p[i-1] + a[i];
  33.     }
  34.  
  35.     // compress values
  36.     vector<int> decompress = p;
  37.     sort(decompress.begin(), decompress.end());
  38.     decompress.resize(unique(decompress.begin(), decompress.end()) - decompress.begin());
  39.     decompress.insert(decompress.begin(), INT_MIN);
  40.     int m = decompress.size();
  41.     auto compress = [&decompress](int x) {
  42.         return lower_bound(decompress.begin(), decompress.end(), x) - decompress.begin();
  43.     };
  44.     for (int &x : p) x = compress(x);
  45.     // p[i] is now the compressed value, decompress[p[i]] is the initial value
  46.  
  47.     // binary search to find smallest loveliness in the composition
  48.     int left = N*(-A), right = N*A+1;
  49.     while (left+1 < right) {
  50.         int mid = (left + right) / 2;
  51.        
  52.         // find how many chords have loveliness >= mid
  53.         long long sufficientlyLovely = 0;
  54.         vector<long long> fenwick(1+m); // indexed by compressed value of prefix sum
  55.         for (int r = 1; r <= n && sufficientlyLovely < k; ++r) { // fix right endpoint of chord
  56.             // chord cannot be longer than R - remove left endpoint
  57.             if (r-R-1 >= 0) update(fenwick, p[r-R-1], -1);
  58.             // chord can be of length L - add new left endpoint
  59.             if (r-L >= 0) update(fenwick, p[r-L], +1);
  60.  
  61.             // decompress[p[r]] - decompress[p[l]] >= mid (l is the index before left endpoint)
  62.             // r-R <= l <= r-L
  63.             int maxPrefixSum = decompress[p[r]] - mid;
  64.             int maxIndex = compress(maxPrefixSum+1)-1;
  65.             sufficientlyLovely += getSum(fenwick, maxIndex);
  66.         }
  67.  
  68.         // check if there are >= k values with loveliness >= mid
  69.         if (sufficientlyLovely >= k) left = mid;
  70.         else right = mid;
  71.     }
  72.  
  73.     int minLoveliness = left;
  74.  
  75.     // find how many chords have loveliness >= minLoveliness, and find their sum
  76.     long long sufficientlyLovelyCnt = 0, sufficientlyLovelySum = 0;
  77.     vector<long long> fenwickCnt(1+m); // indexed by compressed value of prefix sum
  78.     vector<long long> fenwickSum(1+m); // sums over leftpoint prefix sums
  79.     for (int r = 1; r <= n; ++r) { // fix right endpoint of chord
  80.         // chord cannot be longer than R - remove left endpoint
  81.         if (r-R-1 >= 0) {
  82.             update(fenwickCnt, p[r-R-1], -1);
  83.             update(fenwickSum, p[r-R-1], -decompress[p[r-R-1]]);
  84.         }
  85.         // chord can be of length L - add new left endpoint
  86.         if (r-L >= 0) {
  87.             update(fenwickCnt, p[r-L], +1);
  88.             update(fenwickSum, p[r-L], +decompress[p[r-L]]);
  89.         }
  90.  
  91.         // decompress[p[r]] - decompress[p[l]] >= minLoveliness (l is the index before left endpoint)
  92.         // r-R <= l <= r-L
  93.         int maxPrefixSum = decompress[p[r]] - minLoveliness;
  94.         int maxIndex = compress(maxPrefixSum+1)-1;
  95.         long long curCnt = getSum(fenwickCnt, maxIndex);
  96.         sufficientlyLovelyCnt += curCnt;
  97.         long long curSum = curCnt*decompress[p[r]] - getSum(fenwickSum, maxIndex);
  98.         sufficientlyLovelySum += curSum;
  99.     }
  100.  
  101.     long long ans = sufficientlyLovelySum - (sufficientlyLovelyCnt-k)*minLoveliness;
  102.     cout << ans << endl;
  103.     return 0;
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement