题解 CF567D One-Dimensional Battle Ships

这道题可以考虑用 multiset 存储。

multiset 里面维护的是所有无法放置的点。

因此每次操作的时候,我们考虑炮弹射中了点 \(t\) 。 则这个点在这个 multiset 里面的前驱和后继我们记为 \(l\)\(r\) 。那么原来那个长度为 r-l-1 的区间自然就可以拆成长度为 t-l-1r-x-1 的两个区间。自然这个区间长度为 \(x\) 对于答案的贡献是 \(\frac{y+1}{a}\) 。则最终的贡献为原来的贡献减去大区间的贡献加上被分出来的两个区间的贡献。

代码

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int s=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*f;
}
int n,k;
int a,m;
int x;
int tmp,tmp2;
int flag=0;
int ans=0;
multiset<int> s;
int main()
{
	n=read();
	k=read();
	a=read();
	m=read();
	s.insert(0);
	s.insert(n+1);
	ans+=(n/(a+1)+(n%(a+1)==a));
	for(int i=1;i<=m;i++)
	{
		x=read();
		tmp=*(s.lower_bound(x));
		tmp2=*(--s.lower_bound(x));
		ans-=(tmp-tmp2)/(a+1);
		ans+=(tmp-x)/(a+1);
		ans+=(x-tmp2)/(a+1);
		if(ans<k)
		{
			flag=1;
			printf("%d",i);;
			break;
		}
		s.insert(x);
	}
	if(flag==0) puts("-1");
	return 0;
}
posted @ 2021-12-15 22:04  zplqwq  阅读(70)  评论(0)    收藏  举报