纪中暑假集训 2020.07.31【NOIP提高组】模拟 T2:【NOIP2015模拟11.3晚】喝喝喝

【NOIP2015模拟11.3晚】喝喝喝

Description

纪中暑假集训 2020.07.31【NOIP提高组】模拟 T2:【NOIP2015模拟11.3晚】喝喝喝_第1张图片

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

3 2
5 3 1
Sample Output
4
在这里插入图片描述

Data Constraint

在这里插入图片描述

反思&题解

比赛思路: 懵……暴力骗20
正解思路: 枚举每个区间的右端点r,之后通过枚举倍数加上k确定左端点l,用桶记录一下数字,区间的答案贡献即为 r − l r-l rl,最后因为单个数也算一个子序列,所以答案要加上n
反思: 要有“大局观”,不要只关注题目的一个小点,懂得从全局来解题

CODE

#include
using namespace std; 
long long n,k,a[100005],num[100005],ans,tot;
int main()
{
	freopen("drink.in","r",stdin);
	freopen("drink.out","w",stdout);
	scanf("%lld%lld",&n,&k);
	int i;
	for (i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		tot=max(tot,a[i]);
	}
	int l=1,r=2;
	num[a[l]]++;
	while (r<=n)
	{
		i=0;
		int sum=a[r]*i+k;
		if (a[r]>k)
		{
			while (sum<=tot)
			{
				while (num[sum])
				{
					num[a[l]]--;
					l++;
				}
				i++;
				sum=a[r]*i+k;
			}
		}
		ans+=r-l;
		num[a[r]]++;
		r++;
	}
	printf("%lld\n",ans+n);
}

你可能感兴趣的:(反思,题解)