标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 433 Accepted Submission(s): 145
找最左边连续大于x的空间的位置。。
对于一个区间:
符合条件的这个位置要么在最左, 最右, 要么跨越该区间中点 。
否则就递归到左右子区间,并且符合上面的条件。
开一个LL[rt] , RR[rt] 表示区间最左边有多少个空位,最右边有多少连续空位。
就可以维护出来 。
对于题目要开两颗线段树, 一棵是DS+NS的, 一颗是NS的 。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cstring> #include <map> #include <queue> using namespace std; typedef pair<int,int> pii ; #define X first #define Y second #define root 1,n,1 #define lr rt<<1 #define rr rt<<1|1 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int N = 200010; const int mod = 10007; int n , m ; int lazy[N<<2][2] , LL[N<<2][2] , RR[N<<2][2] , ms[N<<2][2]; int s , x , y ; void build( int l , int r , int rt ) { for( int i = 0 ; i < 2 ; ++i ){ ms[rt][i] = LL[rt][i] = RR[rt][i] = r-l+1; // rest from left and right lazy[rt][i] = 0 ; // the state of pushdown } if( l == r ) return ; int mid = (l+r)>>1; build(lson),build(rson); } void Up( int l , int r , int rt , int i ) { int mid = (l+r)>>1; ms[rt][i] = max( max( ms[lr][i] , ms[rr][i] ) , RR[lr][i] + LL[rr][i] ) ; LL[rt][i] = LL[lr][i] ; if( LL[lr][i] == mid - l + 1 ) LL[rt][i] += LL[rr][i]; RR[rt][i] = RR[rr][i]; if( RR[rr][i] == r - mid ) RR[rt][i] += RR[lr][i]; } void Down( int l , int r , int rt , int i ) { if( l == r ) return ; int mid = (l+r)>>1 ; if( lazy[rt][i] == 1 ) { lazy[lr][i] = lazy[rr][i] = 1 ; ms[lr][i] = ms[rr][i] = 0 ; LL[lr][i] = RR[lr][i] = 0 ; LL[rr][i] = RR[rr][i] = 0 ; } if( lazy[rt][i] == -1 ) { lazy[lr][i] = lazy[rr][i] = -1 ; ms[lr][i] = mid - l + 1 ; ms[rr][i] = r - mid ; LL[lr][i] = RR[lr][i] = mid - l + 1 ; LL[rr][i] = RR[rr][i] = r - mid ; } lazy[rt][i] = 0 ; } void relax( int& a , int b ) { if( a == -1 ) a = b ; else a=(a<b?a:b); } void query( int l , int r , int rt , int x , int i ) { if( ms[rt][i] < x ) return ; int mid = (l+r)>>1; if( l == r ) { if( LL[rt][i] == 1 && x == 1 ) relax(s,l) ; return ; } else { Down(l,r,rt,i); if( LL[rt][i] >= x ) relax(s,l) ; if( RR[lr][i] + LL[rr][i] >= x ) relax( s , mid - RR[lr][i] + 1 ); if( RR[rt][i] >= x ) relax(s,r-RR[rt][i]+1); } query(lson,x,i) , query(rson,x,i); Up(l,r,rt,i); } void update( int l , int r , int rt , int L , int R , int i ) { if( l == L && r == R ) { ms[rt][i] = LL[rt][i] = RR[rt][i] = 0 ; lazy[rt][i] = 1 ; return ; } Down( l , r , rt ,i ) ; int mid = (l+r)>>1; if( R <= mid ) update(lson,L,R,i); else if( L > mid ) update(rson,L,R,i); else update(lson,L,mid,i) , update(rson,mid+1,R,i); Up(l,r,rt,i); } void clean( int l , int r , int rt , int L , int R ) { if( l == L && r == R ) { for( int i = 0 ; i < 2 ; ++i ) { LL[rt][i] = RR[rt][i] = ms[rt][i] = r - l + 1 ; lazy[rt][i] = -1 ; } return ; } Down(l,r,rt,0); Down(l,r,rt,1); int mid = (l+r)>>1; if( R <= mid ) clean(lson,L,R); else if( L > mid ) clean(rson,L,R); else clean(lson,L,mid) , clean(rson,mid+1,R); Up(l,r,rt,0); Up(l,r,rt,1); } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif // LOCAL int _ , cas = 1 ; char op[11]; scanf("%d",&_); while( _-- ) { printf("Case %d:\n",cas++); scanf("%d%d",&n,&m); build(root); while( m-- ) { scanf("%s",op); s = -1 ; if( op[0] == ‘D‘ ) { scanf("%d",&x); query(root,x,0); if( s == -1 ) puts("fly with yourself"); else { printf("%d,let‘s fly\n",s); update(root,s,s+x-1,0); } } else if( op[0] == ‘N‘ ) { scanf("%d",&x); query( root , x , 0 ); if( s == -1 ) { query( root , x , 1 ); if( s == -1 ) puts("wait for me"); else { printf("%d,don‘t put my gezi\n",s); update(root,s,s+x-1,1); update(root,s,s+x-1,0); } } else { printf("%d,don‘t put my gezi\n",s); update(root,s,s+x-1,1); update(root,s,s+x-1,0); } } else { scanf("%d%d",&x,&y); puts("I am the hope of chinese chengxuyuan!!"); clean( root , x , y ); } } } }
标签:
原文地址:http://www.cnblogs.com/hlmark/p/4280790.html