题意:大概就是有三种操作吧,第一种在队列后面加入新人,引入一个不耐烦程度,第二种第一个人出队(直接让头结点的序号+1即可),第三种统计在队伍里面不耐烦程度最高的数(PS:随着操作的进行队列中每一个人的不耐烦程度+1),刚开始我是将每个节点加入线段树中,对于每个操作,打上lazy标记,用线段树区间维护,然后TLE了,改了又改,在室友的提醒下,原来我可以把每个加入的节点都统一在第一个节点时插入,只要保证取最大就行,每次执行操作三,选出最大的,然后加上输入第几个操作即可,本来很水的一道题,硬是写了这么久,还是太菜了233333333,直接贴代码了;
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 400005
#define INF 0x3f3f3f3f
using namespace std;
typedef struct node {
int x;
int y;
int date;
int ma;
} node;
node a[4*N];
void built(int root,int first,int end) {
if(first==end) {
a[root].x=first;
a[root].y=end;
a[root].date=0;
a[root].ma=0;
return ;
}
int mid=(first+end)/2;
built(root*2,first,mid);
built(root*2+1,mid+1,end);
a[root].x=a[root*2].x;
a[root].y=a[root*2+1].y;
a[root].date=0;
a[root].ma=0;
}
void Q(int root,int first,int end,int e,int p) {
if(first==e&&end==e) {
a[root].date=p;
return ;
}
int mid=(first+end)/2;
if(e<=mid) Q(2*root,first,mid,e,p);
else Q(2*root+1,mid+1,end,e,p);
a[root].date=max(a[root*2].date,a[root*2+1].date);
}
int sum;
void M(int root,int first,int end,int r,int l) {
if(first>=r&&end<=l) {
sum=max(sum,a[root].date);
return ;
}
int mid=(first+end)/2;
if(r<=mid) M(root*2,first,mid,r,l);
if(l>mid) M(root*2+1,mid+1,end,r,l);
a[root].date=max(a[root*2].date,a[root*2+1].date);
}
int main() {
int m;
while(scanf("%d",&m)==1) {
int n,k;
built(1,1,m);
int fi=1;
int en=0;
int ans=0;
for(int i=1; i<=m; i++) {
scanf("%d",&n);
if(n==1) {
scanf("%d",&k);
en++;
Q(1,1,m,en,k-i+1);
} else if(n==2) {
fi++;
} else if(n==3) {
sum=-INF;
M(1,1,m,fi,en);
printf("%d\n",sum+i-1);
}
}
}
return 0;
}