题解 P7505 【「Wdsr-2.5」小小的埴轮兵团】

题意

维护一个只有出队操作的双端队列。

分析

我们先将埴轮排好序,为了模拟出队操作,我们先定义队头 ll11,队尾 rrnn,若队头出队,只需 l++,若队尾出队,只需 r--,对于每个指令 33,只需输出 r-l+1 即可。

不过,指令 121、2 需要全体坐标全部加或减一个数,暴力去计算会得到 O(nm)O(nm) 的超时复杂度,所以我们可以用一个变量 pp 来表示整体移动的距离,对于每个指令 11,只需令 p+=x,再用 a[r]+p<=k&&l<=r 来判断队尾是否超出范围,并不断进行出队处理;对于每个指令 22,只需令 p-=x,再用 a[l]+p>=-k&&l<=r 来判断队头是否超出范围,并不断进行出队处理。

坑点

xx 最大为 21092* 10^9,多次指令 1122 可能会溢出 int 范围,所以要用 long long

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+10;
int n,m,l=1,r,op;
ll k,a[N],x,p;
int main()
{
    cin>>n>>m>>k;
    r=n;
    for(int i=1;i<=n;i++)
		cin>>a[i];
	sort(a+1,a+n+1);//排序 
	for(int i=1;i<=m;i++)
	{
		cin>>op;
		if(op==3)//操作3 
		{
			cout<<r-l+1<<endl;
			continue;
		}
		cin>>x;
		if(op==1)//操作1 
		{
			p+=x;
			while(a[r]+p>k&&l<=r)//队尾出队 
				r--;
		}
		else//操作2 
		{
			p-=x;
			while(a[l]+p<-k&&l<=r)//队头出队 
				l++;
		}
	}
	return 0;
}
posted @ 2021-04-15 17:19  luckydrawbox  阅读(35)  评论(0)    收藏  举报  来源