pku2823 Sliding Window

离散化+树状数组找第k小元素

SBT又超时了,真搞不明白..

#include  < iostream >
#include 
< algorithm >
using   namespace  std;

#define  MAXN 1000001

int  a[MAXN],c[MAXN],mx[MAXN],mxcnt,n,m;

struct  Node{
    
int  num,tag;
}nod[MAXN];

class  CP{
public :
    
int   operator ()(Node a,Node b){
        
return  a.num < b.num;
    }
};

void  prep(){
    mxcnt
= 0 ;
    memset(c,
0 , sizeof (c));
    
int  i;
    
for (i = 1 ;i <= n;i ++ ){
        scanf(
" %d " , & nod[i].num);
        nod[i].tag
= i;
    }
    sort(nod
+ 1 ,nod + n + 1 ,CP());
    
for (i = 1 ;i <= n;i ++ )
        a[nod[i].tag]
= i;
}

inline 
int  lowbit( int  x){
    
return  x & ( - x);
}

void  insert( int  x, int  t){
    
while (x <= n){
        c[x]
+= t;
        x
+= lowbit(x);
    }
}

int  findk( int  k){
    
int  cnt = 0 ,ans = 0 ;
    
for ( int  i = 20 ;i >= 0 ;i -- ){ // i from log2(n) to 0
        ans += ( 1 << i);
        
if (ans >= ||  cnt + c[ans] >= k)ans -= ( 1 << i);
        
else  cnt += c[ans];
    }
    
return  ans + 1 ;
}

int  main(){
    
int  i;
    
while (scanf( " %d%d " , & n, & m) != EOF){
        prep();
    
        
for (i = 1 ;i <= m;i ++ )
            insert(a[i],
1 );
        printf(
" %d " ,nod[findk( 1 )].num);
        mx[mxcnt
++ ] = nod[findk(m)].num;

        
for (i = 1 ;i <= n - m;i ++ ){
            insert(a[i],
- 1 );
            insert(a[i
+ m], 1 );
            printf(
"  %d " ,nod[findk( 1 )].num);
            mx[mxcnt
++ ] = nod[findk(m)].num;
        }
        printf(
" \n " );
        printf(
" %d " ,mx[ 0 ]);
        
for (i = 1 ;i < mxcnt;i ++ )
            printf(
"  %d " ,mx[i]);
        printf(
" \n " );
    }
    
return   0 ;
}

你可能感兴趣的:(window)