MnZn求助,WAon#17,悬关求调 QAQ
查看原帖
MnZn求助,WAon#17,悬关求调 QAQ
115252
Ciallos楼主2023/8/28 20:28

相关代码内容详见注释,orz

#include <bits/stdc++.h>
#define N 200005
#define ll long long
using namespace std;
ll c,n,len[N],s[N],ma[N],f[N][32];
ll head,tail,down,u;
pair <ll,ll> q[N];
void upd(ll x){
	f[tail][0]=x;
	for (int i=1;i<=30;i++){
		u=tail-(1<<i)+1;
		if (u<1){
			break;
		}
		f[u][i]=max(f[u][i-1],f[u+(1<<(i-1))][i-1]);
	}
}

ll query(ll l,ll r){
	ll k=log2(r-l+1);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}
//平平无奇ST表 

ll get_pos(ll tail,ll tar){//二分寻找严格大于总长度的块 
	ll l=1,r=tail,mid,ans=0;
	while (l<=r){
		mid=(l+r)>>1;
		if (s[mid]>=tar){
			ans=mid;
			r=mid-1;
		}else{
			l=mid+1;
		}
	}
	return ans;
} 

int main (){
	//freopen("queue2.in","r",stdin);
	//freopen("queue.out","w",stdout);
	ll i,j,op,x,pos,l,r,y;
	scanf("%lld%lld",&c,&n);
	head=1,tail=0;
	for (i=1;i<=n;i++){
		scanf("%lld",&op);
		if (op==1){// 
			scanf("%lld",&x);
			q[++tail].first=1,q[tail].second=x;//将[1,x]作为一块加入队列 
			len[tail]=x;//useless 
			s[tail]=s[tail-1]+len[tail];//块的长度的前缀和 
			ma[tail]=x;
			upd(x);// ST表加入新值 
		}
		if (op==2){
			scanf("%lld",&x);
			y=x;
			pos=get_pos(tail,x+down);//pos是长度为 x的序列重点所在的块的编号 
			x=s[pos]-down-x; 
		    down+=y;//down是所有已经删去的长度之和 
		    head=pos;
		    q[pos].first=q[pos].second-x+1;//由终点块往回退更新起点 
		}
		if (op==3){
			scanf("%lld",&x);
			pos=get_pos(tail,x+down);//pos意义同上 
			x=s[pos]-down-x;
			printf("%lld\n",q[pos].second-x);
		}
		if (op==4){// 最大值肯定是[1,X]中的 X ,使用ST表,维护在[head,tail] 内的最大值 
			printf("%lld\n",query(head,tail));
		}
	}
	return 0;
}
2023/8/28 20:28
加载中...