hdu 4614 Vases and Flowers

// 线段树
// 节点保存 区间长度 和 区间的 空闲位置
// 好久没写线段树了 不过除了第一次提交是数组开小导致访问非法内存了外 1Y
// 我写了好多函数 分别求最左区间 最右区间 区间和 区间覆盖
// 不过速度还好 去看了下排名 居然第三 O(∩_∩)O哈! 不过估计不久后就会被刷下去吧

#include <iostream> #include <algorithm> #include <queue> #include <vector> #include <math.h> #include <stdio.h> #include <string.h> using namespace std; #define maxm 100010 #define maxn 50010 #define LL __int64 #define lson l,m,k<<1 #define rson m+1,r,k<<1|1 struct node{ int len; int num;// 代表空位置有多少 }st[maxn<<3]; void build(int l,int r,int k){ st[k].len=r-l+1; st[k].num=st[k].len; // printf("%d %d %d\n",l,r,k); if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } int ansl,ansr; void up(int k){ st[k].num=st[k<<1].num+st[k<<1|1].num; } void down(int k){ if(st[k].num==st[k].len){ st[k<<1].num=st[k<<1].len; st[k<<1|1].num=st[k<<1|1].len; } else if(st[k].num==0){ st[k<<1].num=0; st[k<<1|1].num=0; } } int flag; void left(int L,int R,int l,int r,int k){ // if(flag) return; down(k); if(st[k].num<1) return; if(L<=l&&R>=r&&l==r){ ansl=ansr=l; flag=1; st[k].num--; return ; } int m=(l+r)>>1; if(L<=m) left(L,R,lson); if(R>m) left(L,R,rson); up(k); } int num; void cover(int L,int R,int l,int r,int k){ if(l>r) return ; down(k); int m=(l+r)>>1;//printf("%d %d %d %d\n",l,r,num,st[k].num); if(!st[k].num||!num) return; if(L<=l&&R>=r){ if(st[k].num<=num) {num-=st[k].num; st[k].num=0;return ;} cover(L,R,lson); cover(L,R,rson); }else{ if(L<=m) cover(L,R,lson); if(R>m) cover(L,R,rson); } // if(st[k].num<=num) return; up(k); } void right(int L,int R,int l,int r,int k){ // printf("%d %d %d %d\n",l,r,st[k].num,flag); if(flag) return; down(k); if(st[k].num<1) return; if(L<=l&&R>=r&&l==r){ ansr=l; flag=1; st[k].num--; return ; } int m=(l+r)>>1; if(L<=m) right(L,R,lson); if(R>m) right(L,R,rson); up(k); } int len; void remain(int L,int R,int l,int r,int k){ down(k); if(L<=l&&R>=r){ len+=st[k].num; return; } int m=(l+r)>>1; if(L<=m) remain(L,R,lson); if(R>m) remain(L,R,rson); up(k); } int ans; void clean(int L,int R,int l,int r,int k){ down(k); if(L<=l&&R>=r){ ///printf("====%d %d %d\n",l,r,k); ans+=st[k].len-st[k].num; st[k].num=st[k].len; return ; } int m=(l+r)>>1; if(L<=m) clean(L,R,lson); if(R>m) clean(L,R,rson); up(k); } int main() { int T; scanf("%d",&T); int n,m; int k,a,b; while(T--){ scanf("%d %d",&n,&m); build(0,n-1,1);//printf("?"); while(m--){ scanf("%d %d %d",&k,&a,&b); if(k==1){ flag=0; left(a,n-1,0,n-1,1); if(!flag) {printf("Can not put any one.\n");continue;} // printf("%d %d",ansl,ansr); if(b>1){ num=b-2; len=0; remain(a,n-1,0,n-1,1); if(len){ if(len<=num) num=len-1; // printf("%d ",num); cover(a,n-1,0,n-1,1); flag=0; right(a,n-1,0,n-1,1); } } printf("%d %d\n",ansl,ansr); }else { ans=0; clean(a,b,0,n-1,1); printf("%d\n",ans); } } printf("\n"); } return 0; }

 

posted on 2013-07-25 20:30  江财小子  阅读(318)  评论(0编辑  收藏  举报