题意:现在有n个停车空位。标号为1~n。
现在有两个操作:
操作A:一个车队要求Mi个空位,但是这个车队停的位置有2个约束,Li为车队队首所在位置距离左边最近的那辆车之间的空位不能超过Li(如果车队左边没有车就忽略此条件),Ri为车队队尾所在位置距离右边最近的那辆车之间的空位不能超过Ri,如果存在这样的位置,输出最小的位置。
操作B:从左往右数第k个车队离开

思路:
用一颗线段树维护相应空闲的位置的长度的最小位置,比如说,空闲长度为5的位置有很多的话就取其最小的位置坐标,位置坐标可以用set保存。
再用一颗线段树维护车队的名次。
当车队来的时候要特殊处理是否有忽略的Li和Ri条件。。
然后我在第二颗线段树的时候有一句代码写错WA了整整三天。。卧槽。。。
零零散散的加上调试的代码一共有300+行?
WA/TLE的地方:update1(0,n+1,1,…)写成了update1(1,n,1,…)手残~!!!
代码:

//author: CHC
//First Edit Time: 2015-03-28 22:11
//Last Edit Time: 2015-03-31 09:40
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
using namespace std;
typedef long long LL;
const int MAXN=51000 + 1000;
//const int INF = numeric_limits<int>::max();
const int INF = 0x3f3f3f3f;
const LL LL_INF= numeric_limits<LL>::max();
#define lson L,mid,rt<<1
#define rson mid+1,R,rt<<1|1
struct Tree {
int st,len;
}tr[MAXN<<2],te[MAXN<<2];
set <int> s[MAXN];
void pushup(int rt){
if(tr[rt<<1].st>tr[rt<<1|1].st) tr[rt]=tr[rt<<1|1];
else tr[rt]=tr[rt<<1];
}
void build(int L,int R,int rt){
if(L==R){
s[L].clear();
tr[rt].st=INF;
tr[rt].len=L;
return ;
}
int mid=(L+R)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int rt,int st,int len,int flag){
if(L==R){
if(flag){
s[L].insert(st);
tr[rt].st=*s[L].begin();
}
else {
s[L].erase(st);
if(s[L].begin()==s[L].end()){
tr[rt].st=INF;
}
else {
tr[rt].st=*s[L].begin();
}
}
tr[rt].len=L;
return ;
}
int mid=(L+R)>>1;
if(len<=mid)update(lson,st,len,flag);
else update(rson,st,len,flag);
pushup(rt);
}
Tree query(int L,int R,int rt,int l,int r){
if(l<=L&&R<=r){
return tr[rt];
}
int mid=(L+R)>>1;
Tree t1,t2;
t1.st=INF;t2.st=INF;
if(l<=mid)t1=query(lson,l,r);
if(r>mid)t2=query(rson,l,r);
if(t1.st<t2.st)return t1;
return t2;
}
void pushup1(int rt){
te[rt].st=te[rt<<1].st+te[rt<<1|1].st;
}
void build1(int L,int R,int rt){
if(L==R){
te[rt].st=0;
te[rt].len=0;
return ;
}
int mid=(L+R)>>1;
build1(lson);
build1(rson);
pushup1(rt);
}
void update1(int L,int R,int rt,int st,int len,int flag){
if(L==R){
if(flag){
te[rt].st=1;
te[rt].len=len;
}
else {
te[rt].st=0;
te[rt].len=0;
}
return ;
}
int mid=(L+R)>>1;
if(st<=mid)update1(lson,st,len,flag);
else update1(rson,st,len,flag);
pushup1(rt);
}
void query1(int L,int R,int rt,int rank,int &st,int &len){
if(L==R){
st=L;
len=te[rt].len;
return ;
}
int mid=(L+R)>>1;
if(rank<=te[rt<<1].st)query1(lson,rank,st,len);
else query1(rson,rank-te[rt<<1].st,st,len);
}
/*
void print1(int a,int b){
printf("u1:%d %d\n",a,b);
}
*/
int main()
{
int t,cas=0,n,q;
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&q);
printf("Case #%d:\n",++cas);
//for(int i=0;i<=n;i++)s[i].clear();
//for(int i=0;i<MAXN;i++)tr[i].st=INF;
//memset(te,0,sizeof(te));
build(1,n,1);
update(1,n,1,1,n,1);
build1(0,n+1,1);
update1(0,n+1,1,0,1,1);
update1(0,n+1,1,n+1,1,1);
int st=n,et=n;
char ch;
int x,y,z;
int where,len,sst,start;
for(int i=0;i<q;i++){
//printf("i:%d\n",i);
scanf(" %c",&ch);
if(ch=='A'){
scanf("%d%d%d",&x,&y,&z);
if(st>=x){
update(1,n,1,1,st,0);
if(st==n){
//printf("here\n");
if(n-x>0)
update(1,n,1,x+1,n-x,1);
//printf("%d %d\n",x+1,n-x);
update1(0,n+1,1,1,x,1);
//print1(1,x);
//printf("%d %d\n",1,x);
st=0;et=n-x;
sst=1;
}
else {
//printf("here\n");
if(st>=x+z){
where=st-z+1;
len=z;
update(1,n,1,where,len,1);
update1(0,n+1,1,where-x,x,1);
//print1(where-x,x);
sst=where-x;
st=st-x-z;
if(st){
update(1,n,1,1,st,1);
}
}
else {
len=st-x;
if(len){
//update(1,n,1,len+1,len,1);
update(1,n,1,x+1,len,1);
}
update1(0,n+1,1,1,x,1);
//print1(1,x);
sst=1;
st=0;
}
}
}
else {
//printf("here\n");
Tree tx=query(1,n,1,x,x+y+z);
//printf("%d %d\n",x,x+y+z);
//printf("%d %d\n",tx.st,tx.len);
if(tx.st==INF){
//puts("here11");
//printf("st:%d et:%d\n",st,et);
if(et>=x){
update(1,n,1,n-et+1,et,0);
where=n-(et-x)+1;
len=et-x;
et-=x;
if(len)
update(1,n,1,where,len,1);
//update1(0,n+1,1,n-et+1,x,1);
//sst=n-et+1;
update1(0,n+1,1,where-x,x,1);
//print1(where-x,x);
sst=where-x;
}
else {
sst=-1;
}
}
else {
//printf("\nhere");
update(1,n,1,tx.st,tx.len,0);
//printf("%d %d\n",tx.st,tx.len);
if(tx.st+tx.len-1==n){
sst=tx.st;
//et=len=tx.len-x;
et=len=et-x;
if(len)
update(1,n,1,tx.st+x,len,1);
update1(0,n+1,1,tx.st,x,1);
//print1(tx.st,x);
//et=len;
}
else if(tx.len>=x+z){
len=tx.len-(x+z);
if(len)
update(1,n,1,tx.st,len,1);
//len=z;
update(1,n,1,tx.st+len+x,z,1);
update1(0,n+1,1,tx.st+len,x,1);
//print1(tx.st+len,x);
sst=tx.st+len;
}
else {
len=tx.len-x;
if(len)
update(1,n,1,tx.st+x,len,1);
update1(0,n+1,1,tx.st,x,1);
//print1(tx.st,x);
sst=tx.st;
}
}
}
printf("%d\n",sst);
}
else {
scanf("%d",&x);
++x;
int where1,len1,where2,len2,where3,len3;
if(x<te[1].st){
query1(0,n+1,1,x,where1,len1);
update1(0,n+1,1,where1,len1,0);
query1(0,n+1,1,x-1,where2,len2);
query1(0,n+1,1,x,where3,len3);
//printf("w3:%d w2:%d w1:%d\n",where3,where2,where1);
//printf("l3:%d l2:%d l1:%d\n",len3,len2,len1);
len=where1-(where2+len2);
if(len>0)
update(1,n,1,where2+len2,len,0);
//while(len<0);
//printf("uuu:%d %d\n",where2+len2,len);
len=where3-(where1+len1);
if(len>0)
update(1,n,1,where1+len1,len,0);
//while(len<0);
//printf("uuu:%d %d\n",where1+len1,len);
if(where3-(where2+len2)>0)
update(1,n,1,where2+len2,where3-(where2+len2),1);
//while((where3-(where2+len2))<0);
//printf("uuu:%d %d\n",where2+len2,where3-(where2+len2));
//printf("here1\n");
//printf("%d %d\n",where1,len1);
if(where2==0){
st=where3-(where2+len2);
//while(st<0);
}
if(where3==n+1){
et=where3-(where2+len2);
//while(et<0);
//et=n-(where2+len2)+1;
//puts("here22");
//printf("et:%d\n",et);
//et+=len1+where1-where2-1;
//update(1,n,1,n-et+1,et,1);
}
}
}
//printf("st:%d et:%d\n",st,et);
}
//puts("here");
}
return 0;
}