Codeforces - Bombs

題目鏈接:Codeforces - Bombs


顯然從右往左枚舉的時候,答案具有單調性。

所以我們可以依次看當前的值能否成爲答案。

當前值可以是答案的充要條件爲:存在一個點,這個點後面大於等於ans的個數,大於炸彈數。

所以維護每個點後面大於ans的個數減去炸彈數即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10;
int n,p[N],q[N],pos[N],mx[N<<2],lazy[N<<2],res;
#define mid (l+r>>1)
inline void push_down(int p){
	mx[p<<1]+=lazy[p],mx[p<<1|1]+=lazy[p];
	lazy[p<<1]+=lazy[p],lazy[p<<1|1]+=lazy[p];
	lazy[p]=0;
}
void change(int p,int l,int r,int ql,int qr,int v){
	if(l==ql&&r==qr){mx[p]+=v,lazy[p]+=v; return ;}
	push_down(p);
	if(qr<=mid)	change(p<<1,l,mid,ql,qr,v);
	else if(ql>mid)	change(p<<1|1,mid+1,r,ql,qr,v);
	else change(p<<1,l,mid,ql,mid,v),change(p<<1|1,mid+1,r,mid+1,qr,v);
	mx[p]=max(mx[p<<1],mx[p<<1|1]);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)	scanf("%d",&p[i]),pos[p[i]]=i;
	for(int i=1;i<=n;i++)	scanf("%d",&q[i]); res=n;
	change(1,1,n,1,pos[n],1);	printf("%d ",res);
	for(int i=1;i<n;i++){
		change(1,1,n,1,q[i],-1);
		while(mx[1]<=0)	change(1,1,n,1,pos[--res],1);
		printf("%d ",res);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章