CF1358E Are You Fired?

一、题目

点此看题

二、解法

首先一个合法的答案一定是大于 n 2 \frac{n}{2} 的,因为若 k k 可以, 2 k 2k 一定可以。

然后把 n n 分奇偶讨论,这里只讲奇数的情况,偶数学懂了自己推,请看下图:
在这里插入图片描述
这是 k k 最小的时候,当 k k 增大时,某些部分会增加,某些部分会不合法。我们只需要判断最小的那个是不是正数,要增加都是一起增加的,所以相对大小是不会改变的,我们最开始时处理出的大小关系就可以一直用,这样复杂度就是 O ( n ) O(n)

#include <cstdio>
#include <iostream>
using namespace std;
const int M = 500005;
#define int long long
int read()
{
    int num=0,flag=1;
    char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();
    return num*flag;
}
int n,m,x,a[M],b[M];
signed main()
{
	n=read();
	if(n%2)
	{
		m=n/2+1;
		for(int i=1;i<=m;i++)
			a[i]=read()+a[i-1];
		x=read();b[0]=1e18;
		for(int i=1;i<=m;i++)
			b[i]=min(b[i-1],a[m]-a[i-1]+(i-1)*x);
		for(int i=m;i<=n;i++)
			if(b[2*m-i]+(i-m)*x>0)
			{
				printf("%lld\n",i);
				return 0;
			}
		puts("-1");
	}
	else
	{
		m=n/2;
		for(int i=1;i<=m;i++)
			a[i]=read()+a[i-1];
		x=read();b[0]=1e18;
		for(int i=1;i<=m;i++)
			b[i]=min(b[i-1],a[m]-a[i-1]+i*x);
		for(int i=m+1;i<=n;i++)
			if(b[2*m-i+1]+(i-m-1)*x>0)
			{
				printf("%lld\n",i);
				return 0;
			}
		puts("-1");
	}
}

猜你喜欢

转载自blog.csdn.net/C202044zxy/article/details/107488842