Codeforces Global Round 13 C. Pekora and Trampoline

Codeforces Global Round 13 C. Pekora and Trampoline

Original title portal

General idea

Tell you park with n trampoline, a trampoline each energy value S i , when i-th trampoline jump you, you will jump to S + i- i th trampoline, and S i will be reduced if it is greater than 1 1, but if i+S i is greater than n, then this wonderful trip will be stopped , otherwise, he will continue to jump according to this rule until it stops, and then the question asks you to turn all S i into 1 The minimum number of trips required .

Analysis: Because the data is small, O(n 2 ) can also pass this problem . Here is an O(n) solution, not dsu. I don’t know that. I will use difference to do it.

1. First, let 's consider this matter greedily . We note that for all the S i becomes 1, has become for if we jump, only a move to the right side of a 1 until encountering the first for the S 1 of i . Let us consider the contribution of jumping on a trampoline to the whole. Obviously, it will decrease its S i by 1, and decrease all the points on its path where S j >1 by 1; these points must be on the right side of it. , so S i must have in the position to the right of the point itself and, if out of the community, then the only contribution to the overall contribution have on itself. Very clear and we know that if a S i > 1 and the energy value of the point is greater than 1, and there are only reduced from the point of the operation point, execution of the S i is not present in front of the i -1 Operations.

2. We know that once we jump on a trampoline, the path behind it has been determined. In other words, a path can be represented by the starting point of the path. This is obvious . Then we continue to think about 1. For the first i with S i >1, this S i -1 operation will make the position of the point where it jumps from itself to the left gradually. From the first time S i first starting point is to jump S i + i, and the second is S i + i-1 is the last time ... S i +2. If his S i have no need to proceed to 1, so it must be the last time in S i +2. Then the minimum number of operations required for the point S I -1 times.

3. So the question is, how do we record this information, and how to deal with it. If we follow the above-described operation, the first S I after processing, if the S I there is a point greater than the back (from the S I path starting contribution to the overall Gugu Gu), we have analyzed the S Whether a bit of all the paths started by i is covered by the path, if not, we will continue the operation 1, 2, if there is, we must record and process this information. We have analyzed the 2, a path may be represented by a starting point, the S I path is generated from the S I +2 until S I +. 1-I. We put a mark on these points, considering it is an interval, so we can naturally think of using the difference array, we maintain a difference array d, mark both ends, and if it crosses the boundary, it will hit n+1.

In this way, when we traverse the points from left to right, we use the difference to find the prefix sum, and we know how many times we have traveled to the point of prostitution . If the current travel times of the prostitute is greater than or equal to S j , then this point must have become 1, and for the overflow part, let it go to the right, because it can only jump one square, and it can’t jump anymore . In this way, the next two points are marked with differential marks.

But if the prostitution is not good enough , I have to pay for the trip myself (that is, I return to the situation in 1 at this time), just repeat the above operation . But some people may ask, if I just mark the first point of each dot spread, I don’t know how many squares he can jump after. After all, I have to jump first in the back, and may jump to the repeated point. . No, it doesn’t matter. When we traverse from left to right, we must know the number of prostitution at the current point. This is enough to find the next set of points that it can jump to, because S j can only Little by little, it can only be subtracted by 1 each time. Even if the next point jumps first, we only need to know how many times that point has been used for nothing, it is enough to find the necessary travel expenses for each point.

If we analyze a point directly, assuming that the points before it have been processed, then the number of times the current point is covered by the previous is the number of prostitution. For each trip to the current point, its next point is always It is certain, so we only need to collect a piece of information on the left, and then we will be able to deduce the information at the current point and push it to the right.

(No chicken dishes sprouting new strength) first hair sprouting new solution to a problem, write logic is not very good, ask you to take care of big brother, light spray , primarily to consolidate and use.

The following is the code

#include <iostream>
#include<stdio.h>
#include<algorithm>

using namespace std;
typedef long long ll;
const int N = 1e5+10;
ll t,n,m,q,u,v;
ll s[N],d[N];
void solve(){
    cin>>n;
    for(int i = 1;i <= n;++i){cin>>s[i];d[i] = 0;}
    ll ans = 0;
    for(int i = 1;i <= n;++i){
        d[i] += d[i-1];
        ++d[i+2],--d[min(n,s[i]+i)+1];
        if(d[i] >= s[i])d[i+1] += d[i] - s[i] + 1, d[i+2] -= d[i] - s[i] + 1;
        s[i] = max(s[i]-d[i],1ll);
        ans += s[i] - 1;
    }
    cout<<ans<<endl;
}

int main() {
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    cin>>t;

    while(t--){
        solve();
    }

    fclose(stdin);
    fclose(stdout);
    return 0;
}

Guess you like

Origin blog.csdn.net/yfy20020106/article/details/114261594