CF1687A

The Enchanted Forest

题面翻译

其实这里被称为魔法森林,基本上就是因为这些有幻觉效果的蘑菇。光是接近这些蘑菇,就好像被施了魔法而产生幻觉。——《东方求闻史纪》

魔理沙来到了魔法森林采摘蘑菇。
魔法森林可以被抽象成一条有着 \(n\) 个节点,从 \(1\)\(n\) 标号的数轴。在魔理沙出发之前,她的好友帕秋莉运用魔法去侦测了每个节点上的蘑菇数量,分别为 \(a_1,a_2,\dots,a_n\)
在第 \(0\) 分钟的时候,魔理沙可以从任意一个节点出发。在每一分钟的时候,她将会做以下事情:

  • 她将从节点 \(x\) 移动到节点 \(y\)\(|x-y| \leq 1\),即 \(y\) 可能等于 \(x\)
  • 她将会收集节点 \(y\) 上的所有蘑菇。
  • 魔法森林中每个节点会再生长出一个蘑菇。

注意,她不能在第 \(0\) 分钟的时候收集蘑菇。
现在魔理沙希望知道她在前 \(k\) 分钟的时候,最多能收集到多少个蘑菇。请你帮帮她。

输入格式

第一行输入一个正整数 \(t(1 \leq t \leq 10^4)\),表示输入数据组数。
对于每一组测试数据,第一行输入两个正整数 \(n,k(1 \leq n \leq 2\times 10^5, 1\leq k \leq 10^9)\),含义如题目所述。
第二行输入 \(n\) 个正整数 \(a_i\),表示每个节点上起初有的蘑菇数量。

输出格式

对于每组测试数据输出一行,表示魔理沙最多能收集到多少个蘑菇。

样例 #1

样例输入 #1

4
5 2
5 6 1 2 3
5 7
5 6 1 2 3
1 2
999999
5 70000
1000000000 1000000000 1000000000 1000000000 1000000000

样例输出 #1

12
37
1000000
5000349985
是我太菜了 学校还做过一样的 当时没做出来 现在也思路不是很清晰
分类:k<=n k>n
1.k<=n时 第0秒不动 相当于是走一个长度为k的连续子序列
由于k秒收集到的新长出来的个数是1+2+…+k-1=(k-1)*k/2
所以转化成求长度为k的最大连续子序列和
2.k>n时 可以花费1~n的时间将原有的收集完 问题就转化成
1~k的时间收集到的新长出来的蘑菇的最大个数 相当于就是左右两端来回走
其实用一种后面替代前面的感觉来想:第一次从左走到右相当于漏了1+…+n个
后面去补的时候又会新空出来漏的 反正乱搞一下就是一共漏了1+…+n个
总的新长出的是n*k个所以捡到的就是n*k-(n+1)*n/2个
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t,n,k,a[200005],s[200005];
signed main()
{
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		for(int i=1;i<=n;i++)cin>>a[i],s[i]=s[i-1]+a[i];
		int ans=0;
		if(k<=n)
		{
			for(int i=1;i<=n;i++)
				if(i-k>=0)
					ans=max(ans,s[i]-s[i-k]);
			ans+=k*(k-1)/2;
		}
		else
		{
			ans+=s[n];
			ans+=n*k;
			ans-=(n+1)*n/2;
		}
		cout<<ans<<"\n";
	}
	return 0;
}
疑问:为何是漏的1+…+n? 日后来补
posted @ 2023-01-06 14:40  PKU_IMCOMING  阅读(16)  评论(0)    收藏  举报