codeforces Round #645 (Div. 2)D problem solution

Codeforces Round #645 (Div. 2)——D Problem Solution
As a rookie, of course, there is no A. The data of this problem is too small. Unfortunately, the data card is dead.
The most important point of this question is that you have to come to a conclusion: the last day of the answer must be the end of the month, so that you can enumerate the end of the month, the beginning of the month, the prefix and the number of days to calculate. Specifically, it can be divided into two O(nlogn) or O(n)
. The proof of the conclusion:
Refer to Tutorial and use the contradiction method. Assuming that there is a certain optimal solution and its last day is not the end of the month, let the last day element of the optimal solution be x, you can know that the next day is x+1 (because it is not at the end of the month), because it is the optimal solution, so if the travel plan is delayed by one day, the answer will not be better than the current one, and the travel plan Delaying one day backward means subtracting the element of the left end of the optimal solution plus x+1, so it can be known that the element of the left end is> x+1, so the element of one day to the left of the left end is> x, so we can find that- --- Advance the travel plan by one day, you can add an element> x, subtract an x, and find that the answer is better than the optimal solution, contradictory.
Specific pictures can be combined:

complete approach:

  1. Dichotomous + prefix sum
    Preprocess the prefix and x of the number of days in each month and the prefix of the hug number and the array y of each month.
    Enumerate the last day of each month, that is, for each x[i]>=k, use upper_bound to find the first subscript j of x>x[i]-k (in this case, i represents the end of the month , J represents the month of the first paragraph) Use the prefix and the y array to calculate the number of hugs between the two endpoints (y[i]-y[j-1]). Note that at this time, a part of the hug number is calculated because j The month only contains the endpoints, so use the x array to calculate how many days there are in month j (x[i]-x[j-1]-k), so that the answer minus the number of hugs for that number of days is (t*(t +1)/2) can
    code:
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define ll long long 
ll x[400005];
ll y[400005];
ll z[400005];
int main()
{
    
    
    ll n, m;
    cin >> n >> m;
    int i;
    for (i = 0; i < n; i++)
    {
    
    
        scanf("%d", &x[i]);
        x[i + n] = x[i];
    }
    n = n * 2;
    for (i = 0; i < n; i++)
    {
    
    
        if (i)
        {
    
    
            y[i] = x[i] + y[i - 1];
            z[i] = x[i] * (x[i] + 1) / 2 + z[i - 1];
        }
        else
        {
    
    
            y[i] = x[i];
            z[i] = x[i] * (x[i] + 1);
        }
    }
    ll ma = 0;
    for (i = 0; i < n; i++)
    {
    
    
        if (y[i] >= m)
        {
    
    
            int pos = upper_bound(y, y + n, y[i] - m) - y;
            ll ans = z[i] - z[pos];
            ll days = y[i] - (pos==0?0:y[pos-1]);
            ll cha = days - m;
            
            ans = ans - (cha) * (cha + 1) / 2 + (x[pos]) * (x[pos] + 1) / 2;
            //cout << cha << endl;
            ma = max(ma, ans);
        }
    }
    cout << ma << endl;
}
  1. Take-foot
    general idea and in fact the former is similar to the use of foot to take the idea ---- l, r double pointer, if the current number of days and <k is r ++, may find the end point of the month, then l ++, until in l In the month of the starting endpoint, that is (sum-a[l]=a[l+1]+…+a[r]<k and sum>=k), then calculate the prefix and calculate the answer. .
    I haven't written it myself, so there is no code, but there are many on CF.

Guess you like

Origin blog.csdn.net/ylwhxht/article/details/106390289