lzh的蹦床 差分,贡献,思维

在这里插入图片描述
题意:
给定一个序列a,每次走都会从i跳到i+a[i],并且可以把路径上的数都减去1,和1取max,问最小走多少趟把整个序列变为1。
思路:
由于可以都从1开始遍历,从前往后遍历,考虑第i个数被遍历的时候前面的数对ta造成的影响,由于每个数都要从a[i]降到2,是一段区间,显然可以差分维护,所以假设前面的贡献我们已经更新,我们计算可以少走多少趟,那还有个问题,如果前面的数对他造成的影响溢出了会怎么样呢?那么也就是说a[i]变成1以后又要多走溢出次的累计到后面的差分里去。那么这题就做完了。

// Problem: lzh的蹦床
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/20278/A
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC target("avx")
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
// created by myq 
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int,int> pii;
const int N = 5200;
const int mod=998244353;
inline int read()
{
	int res=0;
	int f=1;
	char c=getchar();
	while(c>'9' ||c<'0')
	{
		if(c=='-')	f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		res=(res<<3)+(res<<1)+c-'0';
		c=getchar(); 
	}
	return res;
 } 
#define int long long
 int n;
 int T;
 int d[N];
 int a[N];
 int b[N];
signed main() 
{
	cin>>T;
	while(T--)
	{
		cin>>n;
	 	ll res=0;
		for(int i=1;i<=n;i++)	scanf("%lld",&a[i]);
		for(int i=1;i<=n;i++){
			d[i]+=d[i-1];
			res+=max(0ll,a[i]-d[i]-1);
			d[i+2]++;
			d[min(n+1,i+1+a[i])]--;
			if(a[i]-d[i]>=1){
				
			}
			else if(a[i]-d[i]<1)
			{
				int k=1-(a[i]-d[i]);
				d[i+1]+=k;
				d[i+2]-=k;
			}
			
		}
		
		cout<<res<<endl;
	      for(int i=1;i<=n+10;i++)
              d[i]=0;
		
	}
	return 0;
	
}
/**
* In every life we have some trouble
* When you worry you make it double
* Don't worry,be happy.
**/



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值