CF1236E Solution

题目链接

题解

⭐:为保证无后效性可以尝试倒序

如果下一个盒子会猜中,便在当前盒子中停留,如此可见对于每一个起始位置,可以到达的最终位置是连续的,因此可以求出其左右端点。设娃娃要由\(i\)号盒子转移至\(j\)号盒子中(\(i<j\)),可以发现在某处停留一次与由\(i-1\)号盒子出发产生的后果相同,因此最右终点位置即为\(i+m-\)停留次数。但是若枚举全部起点时间复杂度为\(O(n^2)\),无法通过。又因为每个猜测\(a_i\)只可影响到\(a_i+i\)\(a_i-i\)两个起点,所以只需将起点\(a_i-i\)的停留次数由\(a_i-i-1\)转移来并\(+1\)。但是同一个起点也许可以受到多次猜测的影响,这时真正影响其的为\(i\)最小的猜测,因此须倒序枚举\(a\)。倒序枚举同时解决了当前停留对之后是否停留的影响,因为其后已处理过了。上述为\(i<j\)(向右移)的情况,\(i>j\)(向左移)同理。

AC代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10,qwq=1e5+10;
int a[N],l[N],r[N];//l/r[i]:以a[i]为起点向左/右移动的停留次数
signed main()
{
	int n,m,ans=0;
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=m;i++) scanf("%lld",&a[i]);
	if(n==1) {printf("0"); return 0;}
	for(int i=m;i>=1;i--) 
		l[a[i]+i+qwq]=l[a[i]+i+1+qwq]+1,r[a[i]-i+qwq]=r[a[i]-i-1+qwq]+1;
	for(int i=1;i<=n;i++)
	{
		int x=max(1ll,i-(m+1)+l[i+qwq]),y=min(n,i+(m+1)-r[i+qwq]);
		ans+=y-x+1;
	}
	printf("%lld",ans);
	return 0;
}	
posted @ 2021-03-25 22:23  violet_holmes  阅读(23)  评论(0编辑  收藏  举报