吉大第二届青云杯复赛第6题

题目链接

题意分析

我就是死在了这道题上

首先我们可以明白的是 所有\(a_i\)增加的上限就是\(lim=Min_{1≤i≤n}b_i\)

然后我们令\(c_i=lim-b_i\)

如果存在\(c_i<0\)的话 那是绝对不符合要求的

这样的话我们的操作就变成了

1.选择一个\(k(1≤k≤n)\)使得所有\(c_1,c_2,...,c_k\)全部\(-1\)

2.选择一个\(k(1≤k≤n)\)使得所有\(c_k,c_{k+1},...,c_n\)全部\(-1\)

然后的话 我们就是躲过这两种操作使得所有\(c_i\)相等并且都是\(≥0\)

当时想到了这里 然后就走歪了 但是当时也明白 这道题的正解应该是比较简单的

但是真正看到正解的那一刻 我还是震惊到了

整体加减 我们想到了什么 差分!!!

我们让\(c_0=0\) 然后的话\(d_i=c_i-c_{i-1}(1≤i≤n)\)

然后我们再回头看这两种操作

1.选择一个\(k(1≤k≤n)\)使得\(d_1-1,d_{k+1}+1\)

2.选择一个\(k(1≤k≤n)\)使得\(d_k-1\)

然后的话 我们就是看看

\[d_1 + \sum_{i=2}^n{[d_i<0]d_i}≥0 \]

这样的话就可以了

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define N 1000080
using namespace std;
int T,n,lim,tot;
bool flag;
int cdy[N],wzy[N],num[N],d[N];
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);lim=2100000000;flag=0;tot=0;
		for(int i=1;i<=n;++i) scanf("%d",&cdy[i]);
		for(int i=1;i<=n;++i) scanf("%d",&wzy[i]);
		for(int i=1;i<=n;++i) lim=min(lim,wzy[i]);
		for(int i=1;i<=n;++i) num[i]=lim-cdy[i];
		for(int i=1;i<=n;++i) if(num[i]<0) {flag=1;break;}
		if(flag) {puts("No");continue;}
		for(int i=1;i<=n;++i) d[i]=num[i]-num[i-1];
		for(int i=1;i<=n;++i)
		if(i==1) tot+=d[i];
		else if(d[i]<0) tot+=d[i];
		if(tot>=0) puts("Yes");
		else puts("No"); 
	}
	return 0;
}
上一篇:极值与凹凸性及简单例题


下一篇:题解 【2020普专提十连测Day7刷题赛】蜂国建设者