程序员的资源宝库

网站首页 > gitee 正文

懒癌 解题报告 懒癌测试题

sanyeah 2024-03-29 16:19:13 gitee 7 ℃ 0 评论

懒癌

先考虑-1的情况,如果一个人知道了自己是特殊的位置,但是\(b>c\),那么就无法判断了

其次,我们考虑一开始有一个不合法的\(a\)的集合,也就是没有特殊位置的集合\(f_0\)

如果在时间\(1\),某一个人的视角下刚好和这个特殊位置重合了(就是除他自己的颜色),那么它就可以报出这个不合法的情况,游戏结束。

如果在时间\(1\)没有发现爆炸,所有人可以得到新的信息:没有人刚好重合。那么此时可以扩展不合法的集合,改变其中的\(f_0\)中任何一个\(a\)的一个位置,在此时仍是不合法的。

以此类推,每个时间过去获得信息并扩展不合法的集合。

现在给了你一个\(a\),需要求出它出现的最小时间。

考虑一个不合法集合是什么样子的

\[a_i+b_i\le a_{i+1}\le a_i+c_i \]

那么可以通过改变最少的\(a\)来达到这个不合法集合(因为每个时间可以变动一个位置)

把条件变一下,令\(B_i,C_i\)代表前缀和(向右移动一位)

那么可以变成对无序二元组\((i,j)\)

\[a_i-B_i\le a_j-B_j\\ a_i-C_i\ge a_j-C_j \]

可以投影到二维平面做最长不上升子序列


Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
#define ll long long
const int N=1e5+10;
template <class T>
void read(T &x)
{
	int f=0;x=0;char c=getchar();
	while(!isdigit(c)) f|=c=='-',c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	if(f) x=-x;
}
int n,cnt;
ll a[N],b[N],c[N],bee[N];
struct koito_yuu
{
	ll a,b;
	koito_yuu(){}
	koito_yuu(ll A,ll B){a=A,b=B;}
	bool friend operator <(koito_yuu a,koito_yuu b){return a.a>b.a;}
}yuu[N];
int main()
{
    freopen("pjz.in","r",stdin);
    freopen("pjz.out","w",stdout);
	read(n);
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=2;i<=n;i++) read(b[i]);
	for(int i=2;i<=n;i++) read(c[i]);
	for(int i=2;i<=n;i++)
		if(b[i]>c[i])
		{
			puts("-1");
			return 0;
		}
	for(int i=2;i<=n;i++) b[i]+=b[i-1],c[i]+=c[i-1];
	for(int i=1;i<=n;i++) yuu[i]=koito_yuu(a[i]-b[i],a[i]-c[i]);
	std::sort(yuu+1,yuu+1+n);
	for(int i=1;i<=n;i++)
	{
		if(!cnt||yuu[i].b>=bee[cnt]) bee[++cnt]=yuu[i].b;
		else bee[std::upper_bound(bee+1,bee+1+cnt,yuu[i].b)-bee]=yuu[i].b;
	}
	printf("%d\n",n-cnt);
	return 0;
}

2019.3.31

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表