• BZOJ 3524: [Poi2014]Couriers( 主席树 )


    卡我空间....

    这道题应该是主席树入门题...无修改 , 离散化都不用...出题人业界良心啊

    一开始的空白树我 build 出来结果就多了整整 2n 个 Node , 然后就 MLE 了...

    ( 双倍经验 , 另一道见上图 ) 

    ----------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
     
    #define rep( i , n ) for( int i = 0 ; i < n ; ++i )
    #define clr( x , c ) memset( x , c , sizeof( x ) )
    #define M( l , r ) ( ( ( l ) + ( r ) ) >> 1 )
     
    using namespace std;
     
    const int maxn = 500000 + 5;
     
    struct Node {
    Node *l , *r;
    int s;
    Node() : s( 0 ) {
    l = r = this;
    }
    inline void update() {
    s = l -> s + r -> s;
    }
    } pool[ 10700000 ] , *pt = pool , *root[ maxn ];
     
    int v;
     
    Node* modify( Node* t , int l , int r ) {
    Node* h = pt++;
    if( l == r )
    h -> s = t -> s + 1;
    else {
    int m = M( l , r );
    if( v <= m ) {
    h -> l = modify( t -> l , l , m );
    h -> r = t -> r;
    } else {
    h -> l = t -> l;
    h -> r = modify( t -> r , m + 1 , r );
    }
    h -> update();
    }
    return h;
    }
     
    int query( Node* L , Node* R , int l , int r ) {
    if( l == r ) return l;
    int m = M( l , r );
    if( R -> l -> s - L -> l -> s > v )
       return query( L -> l , R -> l , l , m );
    else if( R -> r -> s - L -> r -> s > v )
       return query( L -> r , R -> r , m + 1 , r );
    return 0;
    }
     
    int main(){
    freopen( "test.in" , "r" , stdin );
    root[ 0 ] = pt++;
    int n , m;
    cin >> n >> m;
    rep( i , n ) {
    scanf( "%d" , &v );
    root[ i + 1 ] = modify( root[ i ] , 1 , n );
    }
    while( m-- ) {
    int l , r;
    scanf( "%d%d" , &l , &r );
    v = ( r - l + 1 ) >> 1;
    printf( "%d " , query( root[ l - 1 ] , root[ r ] , 1 , n ) );
    }
    return 0;

    ----------------------------------------------------------------------------------------------

    3524: [Poi2014]Couriers

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 782  Solved: 245
    [Submit][Status][Discuss]

    Description

    给一个长度为n的序列a。1≤a[i]≤n。
    m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

    Input

    第一行两个数n,m。
    第二行n个数,a[i]。
    接下来m行,每行两个数l,r,表示询问[l,r]这个区间。

    Output

    m行,每行对应一个答案。

    Sample Input

    7 5
    1 1 3 2 3 4 3
    1 3
    1 4
    3 7
    1 7
    6 6

    Sample Output

    1
    0
    3
    0
    4

    HINT

    【数据范围】

    n,m≤500000


    Source

  • 相关阅读:
    C++细节3
    C++细节2
    C++细节1
    连通域标记方法
    dll动态链接库入门2
    UnixShell编程(第三版)
    Xcode 快捷键
    mysql在linux上的一点操作
    mysql 语句
    开机自动启动
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4649553.html
Copyright © 2020-2023  润新知