本来想用二分来写 用vector调整边界时遇到了点麻烦
改成了很线性的方法 很好懂(
//cyc
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mst(a) memset(a,0,sizeof a)
using namespace std;
typedef pair<int,int> pii;
/*
空を眺めると
そこには僕が居て
*/
const int maxn=1e4+5;
const int maxp=1e6+5;
int recvis[maxn];//占用
int vis[maxn];//差分数组
//
void overall()
{
int rec=0;
for(int i=0;i<maxn;i++){
rec+=vis[i];
recvis[i]=rec;
}
}
int blankcheck(int sz)
{
int st,ed;
st=-1;
int szfit=-1;
int pos=-1;
for(int i=0;i<maxn;i++){
if(!recvis[i]){
if(st==-1)st=i;
ed=i;
}
else{
if(st!=-1){
int len=ed-st+1;
if(len>=sz){
if(szfit==-1){
szfit=len-sz;
pos=st;
}
else{
if(len-sz<szfit){
szfit=len-sz;
pos=st;
}
}
}
}
st=-1;
}
}
return pos;
}
/*
3
1 1000
3000 2000
6000 3000
*/
int psize[maxn];
int pstart[maxn];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,sz,st;
vis[10001]=1;
int cnt=0;
while(true){
char key;
cin>>key;
if(key=='p'){
cout<<"preset"<<endl;
cin>>n;
for(int i=1;i<=n;i++){
cnt++;
cin>>st>>sz;
vis[st]=1;
vis[st+sz]=-1;
overall();
pstart[cnt]=st;
psize[cnt]=sz;
cout<<"process "<<cnt<<" "<<"start from "<<st<<" end at "<<st+sz-1<<endl;
}
}
//overall();
if(key=='a'){
cout<<"add process"<<endl;
cin>>n;
for(int i=1;i<=n;i++){
cin>>sz;
int x=blankcheck(sz);
if(x==-1)cout<<"impossible"<<endl;
else{
cnt++;
vis[x]+=1;
vis[x+sz]+=-1;
overall();
pstart[cnt]=x;
psize[cnt]=sz;
cout<<"process "<<cnt<<" "<<"start from "<<x<<" end at "<<x+sz-1<<endl;
}
}
}
if(key=='r'){
cout<<"remove process"<<endl;
cin>>n;
for(int i=1;i<=n;i++){
int p;
cin>>p;
if(p>cnt)cout<<"bound exceed"<<endl;
else{
vis[pstart[p]]=0;
vis[pstart[p]+psize[p]]=0;
overall();
cout<<"process "<<p<<" released"<<endl;
}
}
}
}
}