這題卡了我很久!不過也給了我很多的啟示.. 因為自己對線段樹的理解還是很淺顯的所以這個題也便總是過不了,一直卡著卡著。遵照三鮮的原則,現在我做題極少看別人的代碼,但是又沒有人可以和我一起討論的,所以今天還是看了下別人的解題報告,因為我想不出了,看著看著我發現了一個問題----->我丫的把題目讀錯了!太2了!區間合并線段樹已經學習的差不多了,可能會在小的細節方面出點叉子,但是對基本的線段樹運用的得還不錯了。認真的去體會線段樹的美,二叉的精巧,與構思的美妙。還是那句話:二叉樹只是一個資料結構,類似於其他的資料結構一樣,要有演算法的輔助才能體現得出他的美。
決定要向那些大牛們學習,做一個勤奮的好孩子~雖然和他們沒得什麼聯絡... 有目標總歸是好的。
在這題中學會了使用vector容器,我編碼極少用STL,也沒有什麼機會用。不過用起來還是挺舒服的,功能強大啊~另外對於二分尋找也有了新的感悟,本來在有序的序列中,就可以不用夾逼法了,定義一個維度就OK了~因為原來看錯題,導致查詢工作不能使用二分尋找,於是便悲催得~~
另外給我的啟示就是對於二叉樹,不一定非得全部放在樹形結構裡面做,可以另外定義變數,開始我自己想思路的時候想把所有的操作都置於樹形結構中做,但是發現這樣做下去很困難!實現困難,尋找也麻煩。後來改成了兩個一維數組來額外存貯這部分的資訊,於是乎,代碼實現起來也簡便了。所以線段樹要活學活用~
加油!!
#include<stdio.h>#include<vector>using namespace std;#define MAXN 50005struct node{ int ltemp,rtemp,mtemp;}tree[MAXN<<2];int col[MAXN<<2];struct block{ int s,t; block( int a,int b ){ s=a,t=b; }};vector<block> B;int max( int a,int b ){ return a>b?a:b; }void PushUp( int rt , int m ){ tree[rt].ltemp=tree[rt<<1].ltemp; tree[rt].rtemp=tree[rt<<1|1].rtemp; if( tree[rt].ltemp==m-(m>>1) ) tree[rt].ltemp+=tree[rt<<1|1].ltemp; if( tree[rt].rtemp==m>>1 ) tree[rt].rtemp+=tree[rt<<1].rtemp; tree[rt].mtemp=max( tree[rt<<1|1].ltemp+tree[rt<<1].rtemp,max( tree[rt<<1].mtemp,tree[rt<<1|1].mtemp) );}void PushDown( int rt,int m ){ if( col[rt]!=-1 ) { col[rt<<1]=col[rt<<1|1]=col[rt]; tree[rt<<1].ltemp=tree[rt<<1].mtemp=tree[rt<<1].rtemp=col[rt]?0:(m-(m>>1)); tree[rt<<1|1].ltemp=tree[rt<<1|1].mtemp=tree[rt<<1|1].rtemp=col[rt]?0:(m>>1); col[rt]=-1; }}void build( int l,int r,int rt ){ col[rt]=-1; tree[rt].ltemp=tree[rt].mtemp=tree[rt].rtemp=r-l+1; if( l==r )return ; int m=( l+r )>>1; build( l,m,rt<<1 ); build( m+1,r,rt<<1|1 );}int query( int w,int l,int r,int rt ){ int m=( l+r )>>1; if( l==r ) return l; PushDown( rt,r-l+1 ); if( tree[rt<<1].mtemp>=w ) return query( w,l,m,rt<<1 ); else if( tree[rt<<1|1].ltemp+tree[rt<<1].rtemp>=w ) return m-tree[rt<<1].rtemp+1; else return query( w,m+1,r,rt<<1|1 );}void update( int l,int r,int c,int L,int R,int rt ){ if( l<=L&&R<=r ) { col[rt]=c; tree[rt].ltemp=tree[rt].mtemp=tree[rt].rtemp=col[rt]?0:R-L+1; return ; } PushDown( rt,R-L+1 ); int m=( L+R )>>1; if( l<=m ) update( l,r,c,L,m,rt<<1 ); if( r>m ) update( l,r,c,m+1,R,rt<<1|1 ); PushUp( rt,R-L+1 );}int Bin( int at ){ int left=0;int right=B.size()-1; int m; while( left<=right ) { m=( left+right )>>1; if( at>=B[m].s ) left=m+1; else right=m-1; } return left;}int main(){ int n,m; char com[10]; int date,i; while( scanf("%d %d",&n,&m)!=EOF ) { build( 1,n,1 ); B.clear(); while( m-- ) { scanf( "%s",&com ); if( com[0]=='N' ) { scanf( "%d",&date ); if( date>tree[1].mtemp ) printf( "Reject New\n" ); else { int at=query( date,1,n,1 ); block k(at,at+date-1); int index=Bin(at);//printf( "%d\n",index ); B.insert( B.begin()+index,k ); update( at,at+date-1,1,1,n,1 ); printf( "New at %d\n",at ); } } else if( com[0]=='R' ) { update(1,n,0,1,n,1); B.clear(); printf( "Reset Now\n" ); } else if( com[0]=='G' ) { scanf( "%d",&date ); if( date>B.size() ) { printf( "Reject Get\n" ); continue; } else printf( "Get at %d\n",B[date-1].s ); } else if( com[0]=='F' ) { scanf( "%d",&date ); int index=Bin(date)-1; //printf( "%d\n",index ); if( index!=-1 && B[index].t>=date ) { printf( "Free from %d to %d\n",B[index].s,B[index].t ); update( B[index].s,B[index].t,0,1,n,1 ); B.erase( B.begin()+index ); } else printf( "Reject Free\n" ); } } printf( "\n" ); } return 0;}