• 2015.7.17( NOI2015 day1 )


    今天早起做了NOI2015网络同步赛....

    最近NOI是越来越向NOIP靠拢了....但是我还是不会做.....

     

    第一题:程序自动分析

    先离散化一下..然后最多就剩20w个数 , 不等于就存起来..等于就用并查集维护...最后for判断一下就行了.....

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cctype>
    #include<cstdlib>
     
    #define rep(i ,n) for(int i=0; i < n; ++i)
    #define clr(x ,c) memset(x, c, sizeof(x))
     
    using namespace std;
     
    const int maxn = 200005;
     
    struct T {
    int x;
    T* next;
    } *head[ maxn ] , pool[ maxn ] , *pt;
     
    void add( int u , int v ) {
    pt -> x = v;
    pt -> next = head[ u ];
    head[ u ] = pt++;
    }
     
    inline int read() {
    char c = getchar();
    int ans = 0;
    for( ; ! isdigit( c ) ; c = getchar() );
    for( ; isdigit( c ) ; c = getchar() )
       ans = ans * 10 + c - '0';
    return ans;
    }
     
    int fa[ maxn ];
     
    int find( int x ) {
    return x == fa[ x ] ? x : fa[ x ] = find( fa[ x ] );
    }
     
    struct Q {
    int x , y;
    bool type;
    } q[ maxn ];
     
    int id[ maxn << 1 ];
     
    int main(){
    freopen("prog.in", "r", stdin);
    freopen("prog.out", "w", stdout);
    int t = read();
    while( t-- ) {
    int cnt = 0;
    pt = pool;
    int n = read();
    rep( i , n ) {
    Q &p = q[ i ];
       id[ cnt++ ] = p.x = read();
    id[ cnt++ ] = p.y = read();
    p.type = read();
    }
    sort( id , id + cnt );
    cnt = unique( id , id + cnt ) - id;
    rep( i , cnt ) fa[ i ] = i;
    clr( head , 0 );
    rep( i , n ) {
    Q* p = q + i;
    if( p -> type ) 
       fa[ find( lower_bound( id , id + cnt , p -> x ) - id ) ] = 
           find( lower_bound( id , id + cnt , p -> y ) - id );
    else 
       add( lower_bound( id , id + cnt , p -> x ) - id ,
            lower_bound( id , id + cnt , p -> y ) - id );
    }
    bool ans = true;
    rep( i , cnt ) {
    for( T* p = head[ i ] ; p ; p = p -> next ) {
       if( find( i ) == find( p -> x ) ) {
        ans = false;
        break;
       }
    }
    if( ! ans ) break;
    }
    printf( ans ? "YES " : "NO " );
    }
    return 0;

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

     第二题 : 软件包管理器

    树链剖分... install( x ) 就处理 x 到 root 的这条路径 , uninstall( x ) 就处理以 x 为根的子树...子树在线段树上是连续的.. 两个操作都可以打标...话说我对拍时暴力程序也跑得很快...难道暴力也能过 ?

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cctype>
    #include<cstdlib>
     
    #define rep(i ,n) for(int i=0; i < n; ++i)
    #define clr(x ,c) memset(x, c, sizeof(x))
    #define REP( x ) for( edge* e = head[ x ] ; e ; e = e -> next )
    #define M( l , r ) ( ( ( l ) + ( r ) ) >> 1 )
     
    using namespace std;
     
    const int maxn = 100000 + 5;
     
    struct edge {
    int to;
    edge* next;
    } E[ maxn << 1 ] , *ptt = E , *head[ maxn ];
     
    inline void add( int u , int v ) {
    ptt -> to = v;
    ptt -> next = head[ u ];
    head[ u ] = ptt++;
    }
    #define add_edge( u , v ) add( u , v ) , add( v , u )
     
    int top[ maxn ] , fa[ maxn ] , dep[ maxn ] , size[ maxn ] , son[ maxn ];
    int id[ maxn ] , id_cnt = 0 , TOP , n , _L[ maxn ] , _R[ maxn ];
     
    void dfs( int x ) {
    size[ x ] = 1 , son[ x ] = -1;
    REP( x ) {
    int to = e -> to;
    if( to == fa[ x ] ) continue;
    dep[ to ] = dep[ x ] + 1;
    fa[ to ] = x;
    dfs( to );
    size[ x ] += size[ to ];
    if( son[ x ] == -1 || size[ son[ x ] ] < size[ to ] ) 
      son[ x ] = to;
    }
    }
     
    void DFS( int x ) {
    top[ x ] = TOP;
    _L[ x ] = id[ x ] = ++id_cnt;
    if( son[ x ] != -1 ) DFS( son[ x ] );
    REP( x ) if( fa[ x ] != e -> to && e -> to != son[ x ] )
       DFS( TOP = e -> to );
    _R[ x ] = id_cnt;
    }
     
    void init() {
    dfs( dep[ 0 ] = 0 );
    DFS( TOP = 0 );
    }
     
    struct Node {
    Node *l , *r;
    int set , sum; // sum : sum of install
    Node() {
    set = sum = 0;
    l = r = NULL;
    }
    inline void update( int len ) {
    if( set != -1 )
       sum = set * len;
    else 
       sum = l -> sum + r -> sum;
    }
    inline void pushdown() {
    if( set != -1 ) {
    l -> set = r -> set = set;
    set = -1;
    }
    }
    } pool[ maxn << 1 ] , *pt = pool , *root;
     
    void build( Node* t , int l , int r ) {
    if( r > l ) {
    int m = M( l , r );
    build( t -> l = pt++ , l , m );
    build( t -> r = pt++ , m + 1 , r );
    }
    }
     
    int L , R;
    bool v;// v -> true install
     
    void modify( Node* t , int l , int r ) {
    if( L <= l && r <= R ) {
    t -> set = v;
    } else {
    int m = M( l , r );
    t -> pushdown();
    L <= m ? modify( t -> l , l , m ) : t -> l -> update( m - l + 1 );
    m < R ? modify( t -> r , m + 1 , r ) : t -> r -> update( r - m );
    }
    t -> update( r - l + 1 );
    }
     
    int query( Node* t , int l , int r ) {
    if( L <= l && r <= R )
    return v ? r - l + 1 - t -> sum : t -> sum;
    int m = M( l , r );
    t -> pushdown();
    t -> l -> update( m - l + 1 );
    t -> r -> update( r - m );
    return ( L <= m ? query( t -> l , l , m ) : 0 ) + 
          ( m < R ? query( t -> r , m + 1 , r ) : 0 );
    }
     
    int install( int x , int y ) {
    int ans = 0;
    while( top[ x ] != top[ y ] ) {
    if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y );
    L = id[ top[ x ] ] , R = id[ x ];
    ans += query( root , 1 , n );
    modify( root , 1 , n );
    x = fa[ top[ x ] ];
    }
    if( dep[ x ] < dep[ y ] ) swap( x , y );
    L = id[ y ] , R = id[ x ];
    ans += query( root , 1 , n );
    modify( root , 1 , n );
    return ans;
    }
     
    inline int read() {
    char c = getchar();
    int ans = 0;
    for( ; ! isdigit( c ) ; c = getchar() );
    for( ; isdigit( c ) ; c = getchar() )
       ans = ans * 10 + c - '0';
    return ans;
    }
     
    int main(){
    freopen("manager.in", "r", stdin);
    freopen("manager.out", "w", stdout);
    clr( head , 0 );
    n = read();
    build( root = pt++ , 1 , n );
    rep( i , n - 1 ) {
    int t = read();
       add_edge( t , i + 1 );
    }
    init();
    int q = read() , x;
    char s[ 10 ];
    while( q-- ) {
    scanf( "%s%d" , s , &x );
    if( s[ 0 ] == 'i' ) {
    v = true;
    printf( "%d " , install( 0 , x ) );
    } else {
    v = false;
    L = _L[ x ] , R = _R[ x ];
    printf( "%d " , query( root , 1 , n ) );
    modify( root , 1 , n );
    }
    }
    return 0;

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

    第三题 : 寿司晚宴

    完全不会..但是打表还能弄点分吧....暴力程序打个表然后就30分了...

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cctype>
    #include<cstdlib>
     
    #define rep(i ,n) for(int i=0; i < n; ++i)
    #define clr(x ,c) memset(x, c, sizeof(x))
     
    using namespace std;
     
    typedef long long ll;
     
    const int maxn = 50;
    ll ans[ maxn ];
     
    int main(){
    freopen("dinner.in", "r", stdin);
    freopen("dinner.out", "w", stdout);
    ans[ 2 ] = 3;
        ans[ 3 ] = 9;
        ans[ 4 ] = 21;
        ans[ 5 ] = 63;
        ans[ 6 ] = 111;
        ans[ 7 ] = 333;
        ans[ 8 ] = 693;
        ans[ 9 ] = 1521;
        ans[ 10 ] = 2577;
        ans[ 11 ] = 7731;
        ans[ 12 ] = 13491;
        ans[ 13 ] = 40473;
        ans[ 14 ] = 67833;
        ans[ 15 ] = 119241;
        ans[ 16 ] = 239481;
        ans[ 17 ] = 718443;
        ans[ 18 ] = 1340523;
        ans[ 19 ] = 4021569;
        ans[ 20 ] = 7494849;
        ans[ 21 ] = 13356657;
        ans[ 22 ] = 22271409;
        ans[ 23 ] = 66814227;
        ans[ 24 ] = 130266387;
        ans[ 25 ] = 268286823;
        ans[ 26 ] = 447212583;
        ans[ 27 ] = 896472063;
        ans[ 28 ] = 1684872063;
        ans[ 29 ] = 5054616189;
    ll n , MOD;
    cin >> n >> MOD;
        if( n < 30 ) cout << ans[ n ] % MOD << " ";
        else cout << 1LL * rand() * rand() % MOD << " ";
    return 0;

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

     后天还有day2...没玩过提答题 , 挺想玩的....

  • 相关阅读:
    预处理、const、static与sizeof-为什么不把所有的函数都定义成内联函数
    预处理、const、static、sizeof-说明内联函数使用的场合
    预处理、const、static、sizeof-为什么inline能很好地取代表达式形式的预定义
    预处理、const、static与sizeof-为什么要引入内联函数
    预处理、const、static与sizeof-#pragma pack的作用
    预处理、const、static与sizeof-sizeof与strlen有哪些区别
    预处理、const、static与sizeof-static全局变量与普通的全局变量有什么区别
    预处理、const、static与sizeof-static有什么作用(至少说出2个)
    预处理、const、static与sizeof-C++中const有什么作用(至少说出3个)
    预处理、const、static与sizeof-使用const与#define的特点及区别
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4654928.html
Copyright © 2020-2023  润新知