Uva 12299 RMQ with Shifts(线段树 + 单点更新 )

 

 

Uva 12299 RMQ with Shifts (线段树 + 单点更新)


题意:
对于给定的序列 x[i]
给出一个操作 shift(a,b,c,d,e) 对应的是将 x[a]与x[b] x[b]与x[c] 这样相邻的两两交换
For example, if A={6, 2, 4, 8, 5, 1, 4}
then shift(2, 4, 5, 7) yields {6, 8, 4, 5, 4, 1, 2}.
After that,shift(1, 2) yields
{8, 6, 4, 5, 4, 1, 2}.


分析: 
实际上也是单点更新,考虑的时候考虑复杂了,
这里有一个关键点是 shift[0]最后移动到shift[cnt-1]的位置
其他就是基本的单点更新操作了。


           --cnt;

           int t = x[shift[0]];

           REP( i, 0, cnt )

           {

               x[shift[i]] = x[shift[i+1]];

               Update( shift[i], x[shift[i]], 1, n, 1 );

           }

           x[shift[cnt]] = t;

           Update( shift[cnt], x[shift[cnt]], 1, n, 1 );        

 
  

 

//#define BUG

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <map>

#include <vector>

#include <list>

#include <queue>

#include <ctime>

#include <iostream>

#include <cmath>

#include <set>

#include <string>

using namespace std;

typedef long long LL;

typedef unsigned long long ULL;

#define INF                 0x7fffffff

#define MAX                 0x3f3f3f3f



#define CLR( a, b )         memset( a, b, sizeof(a) )

#define REP( i, a, b )      for( int i = (a); i < (b); ++i )

#define FOR( i, a, b )      for( int i = (a); i <=(b); ++i )

#define FOD( i, a, b )      for( int i = (a); i >=(b); --i )



#define MID                 ( l + r ) >> 1

#define lson                l, m, o << 1

#define rson                m + 1, r, o << 1 | 1

#define ls                  o << 1

#define rs                  o << 1 | 1

#define MAXN                100010



int tree[MAXN << 2];

int x[MAXN];

int cnt;

int shift[33];

char str[33];



void PushUp( int o )

{

    tree[o] = min( tree[ls], tree[rs] );

}



void Build( int l, int r, int o )

{

    if( l == r )

    {

        tree[o] = x[l];

        return;

    }

    int m = MID;

    Build( lson );

    Build( rson );

    PushUp( o );

}



void Update( int pos, int v, int l, int r, int o )

{

    if(l == r)

    {

        tree[o] = v;

        return;

    }

    int m = MID;

    if( pos <= m )  Update( pos, v, lson );

    else            Update( pos, v, rson );

    PushUp( o );

}



int Query( int L, int R, int l, int r, int o )

{

    if( L == l && r == R )

    {

        return tree[o];

    }

    int m = MID;

    if( R <= m )    return Query( L, R, lson);

    else if( L > m ) return Query( L, R, rson);

    else

    {

        return min( Query( L, m, lson ), Query( m + 1, R, rson ) );

    }

}



int GetOP()

{

    CLR( shift, 0 );

    cnt = 0;

    scanf( "%s", str );

    int i = 0;

    while( str[i] )

    {

        int t = 0;

        int flag = 0;

        while( str[i] >= '0' && str[i] <= '9' )

        {

            flag = 1;

            t = t*10 + str[i] - '0';

            i++;

        }

        if( flag )

            shift[ cnt++ ] = t;

        else

            i++;

    }

    /*

    puts("");

    for(int i=0;i<cnt;i++)

        printf( "%d ", shift[i] );

    puts("");

    */

    if(str[0] == 'q')

        return true;

    else

        return false;

}



void Orz()

{

    #ifdef  BUG

        freopen("in.txt","r",stdin);

    #endif

    int n, p;

    scanf( "%d %d", &n, &p );

    FOR( i, 1, n )

        scanf( "%d",&x[i] );

    Build( 1, n, 1 );

    while( p-- )

    {

       if( GetOP() )

       {

           printf( "%d\n", Query( shift[0], shift[1], 1, n, 1 ) );

       }

       else

       {

           --cnt;

           int t = x[shift[0]];

           REP( i, 0, cnt )

           {

               x[shift[i]] = x[shift[i+1]];

               Update( shift[i], x[shift[i]], 1, n, 1 );

           }

           x[shift[cnt]] = t;

           Update( shift[cnt], x[shift[cnt]], 1, n, 1 );

       }

    }

}



int main()

{

    Orz();

    return 0;

}
代码君

 

 

你可能感兴趣的:(with)