HDU 2871 Memory Control
线段树各种操作+STL
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn=50000+10; struct SegTree { int lsum; int rsum; int msum; int cover; }segTree[4*maxn]; struct block { int begin, end; }; vector<block>v; int N,Q,x; char op[10]; bool cmp(const block &a, const block &b) { return a.begin < b.begin; } void pushUp(int rt,int len) { if(segTree[2*rt].lsum==len-len/2) segTree[rt].lsum=segTree[2*rt].lsum+segTree[2*rt+1].lsum; else segTree[rt].lsum=segTree[2*rt].lsum; if(segTree[2*rt+1].rsum==len/2) segTree[rt].rsum=segTree[2*rt].rsum+segTree[2*rt+1].rsum; else segTree[rt].rsum=segTree[2*rt+1].rsum; segTree[rt].msum=max(segTree[2*rt].msum,segTree[2*rt+1].msum); segTree[rt].msum=max(segTree[rt].msum,segTree[2*rt+1].lsum+segTree[2*rt].rsum); } void pushDown(int rt,int len) { if(segTree[rt].cover!=-1) { segTree[2*rt].lsum=segTree[2*rt].rsum=segTree[2*rt].msum=(segTree[rt].cover?0:len-len/2); segTree[2*rt+1].lsum=segTree[2*rt+1].rsum=segTree[2*rt+1].msum=(segTree[rt].cover?0:len/2); segTree[2*rt].cover=segTree[2*rt+1].cover=segTree[rt].cover; segTree[rt].cover=-1; } } void build(int l,int r,int rt) { segTree[rt].lsum=r-l+1; segTree[rt].rsum=r-l+1; segTree[rt].msum=r-l+1; segTree[rt].cover=-1; if(l==r) return; int m=(l+r)/2; build(l,m,2*rt); build(m+1,r,2*rt+1); pushUp(rt,r-l+1); } void Update(int info,int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { segTree[rt].cover=info; segTree[rt].lsum=segTree[rt].rsum=segTree[rt].msum=(info?0:r-l+1); return; } pushDown(rt,r-l+1); int m=(l+r)/2; if(L<=m) Update(info,L,R,l,m,2*rt); if(R>=m+1) Update(info,L,R,m+1,r,2*rt+1); pushUp(rt,r-l+1); } int Quary(int info,int l,int r,int rt) { if(l==r) return l; int m=(l+r)/2; pushDown(rt,r-l+1); if(segTree[2*rt].msum>=info) return Quary(info,l,m,2*rt); else if(segTree[2*rt].rsum+segTree[2*rt+1].lsum>=info) return m-segTree[2*rt].rsum+1; else if(segTree[2*rt+1].msum>=info) return Quary(info,m+1,r,2*rt+1); pushUp(rt,r-l+1); } int main() { //freopen("F:\\in.txt","r",stdin); //freopen("F:\\out.txt","w",stdout); while(~scanf("%d%d",&N,&Q)) { v.clear(); build(1,N,1); while(Q--) { scanf("%s",op); if(op[0]=='R') { Update(0,1,N,1,N,1); v.clear(); printf("Reset Now\n"); } else if(op[0]=='N') { scanf("%d",&x); if(segTree[1].msum<x) printf("Reject New\n"); else{ int pos=Quary(x,1,N,1); printf("New at %d\n",pos); block y; y.begin = pos, y.end = pos + x - 1; vector<block>::iterator it; it = upper_bound(v.begin(), v.end(), y, cmp); v.insert(it, y); Update(1,pos,pos+x-1,1,N,1); } } else if(op[0]=='F') { scanf("%d", &x); block y; y.begin = x, y.end = x; vector<block>::iterator it; it = upper_bound(v.begin(), v.end(), y, cmp); int tmp = it - v.begin() - 1; if (tmp == - 1 || v[tmp].end < x) printf("Reject Free\n"); else { printf("Free from %d to %d\n", v[tmp].begin, v[tmp].end); Update(0,v[tmp].begin,v[tmp].end,1,N,1); v.erase(v.begin() + tmp); } } else if(op[0]=='G') { scanf("%d", &x); if (x > v.size()) printf("Reject Get\n"); else printf("Get at %d\n", v[x-1].begin); } } printf("\n"); } return 0; }