Codeforce 1491C Pekora and Trampoline (Thinking + Difference)

Topic link


The main idea of ​​the topic: There are n trampolines, and each trampoline has a jumping distance. Each trampoline jump will reduce the jumping distance by 1, and the jumping distance is max(1,a[i]). You can choose any trampoline to start, and ask you to go through at least a few rounds to change the bounce distance of all trampolines to 1.


Idea: Differential maintenance
First of all, we need to convert everything into 1, then the optimal method is to start jumping from the first trampoline greater than 1, which must be optimal. Let’s assume that the first one is a[i], then he jumps to (i+a[i]) for the first time, and then jumps to (i+a[i]-1) for the second time...knowing the last time from point i When you start to jump, jump to (i+2). I jumped (a[i]-1) times in total.
Pay attention to this place: In fact, it is to accumulate and jump to this place before.

 if(tmp<1) {
    
    
                if(i+1<=n) {
    
    
                    b[i+1]+=(1-tmp);///会前面变1走的次数
                }
                if(i+2<=n) {
    
    
                    b[i+2]-=(1-tmp);///后端维护了
                }
}
#include <set>
#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e5+10;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=1e9+7;
const int MOD=1e9+7;

inline int read() {
    
    
    int x=0;
    bool t=false;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
ll n,m,d;
ll a[maxn],b[maxn];
ll ans;
string str;
int main() {
    
    
    ll t;
    cin>>t;
    while(t--) {
    
    
        cin>>n;
        for(int i=1; i<=n; i++) {
    
    
            scanf("%lld",&a[i]);
            b[i]=0;
        }
        ans=0;
        for(int i=1; i<=n; i++) {
    
    
            b[i]+=b[i-1];///积累贡献
        ///cout<<"i  "<<i<<"b[i]***"<<b[i]<<endl;
            ll tmp=a[i]-b[i];///是否还需要跳
            if(tmp>1) ans+=tmp-1;///需要
            if(a[i]>1) {
    
    
                if(i+2<=n) {
    
    ///最后一次跳
                    b[i+2]++;///维护差分
                }
                if(i+a[i]+1<=n) {
    
    
                    b[i+a[i]+1]--;///维护差分
                }
            }
            if(tmp<1) {
    
    
                if(i+1<=n) {
    
    
                    ///cout<<i<<"(1-tmp)"<<1-tmp<<endl;
                    ///cout<<"b[i+1]"<<b[i+1]<<" ";
                    b[i+1]+=(1-tmp);///会前面变1走的次数
                    ///cout<<"ab[i+1]"<<b[i+1]<<endl;
                }
                if(i+2<=n) {
    
    
                    ///cout<<i<<"(1-tmp)"<<1-tmp<<endl;
                    ///cout<<"b[i+2]"<<b[i+2]<<" ";
                    b[i+2]-=(1-tmp);///后端维护了
                    ///cout<<"ab[i+2]"<<b[i+2]<<endl;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


Guess you like

Origin blog.csdn.net/weixin_45911397/article/details/114733373