UVA 12299

来源:互联网 发布:淘宝运营需要会什么 编辑:程序博客网 时间:2024/06/05 12:05

  RMQ with Shifts 

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (LR)(L$ \le$R), we report the minimum value among A[L]A[L + 1], ..., A[R]. Note that the indices start from 1, i.e. the left-most element is A[1].

In this problem, the array A is no longer static: we need to support another operation

shift(i1i2i3,..., ik)(i1 < i2 < ... < ikk > 1)

we do a left ``circular shift" of A[i1]A[i2], ..., A[ik].

For example, if A={6, 2, 4, 85, 1, 4}, then shift(2, 4, 5, 7) yields {68, 4, 5, 4, 1, 2}. After that,shift(1, 2) yields 8, 6, 4, 5, 4, 1, 2.

Input 

There will be only one test case, beginning with two integers nq ( 1$ \le$n$ \le$100, 0001$ \le$q$ \le$250, 000), the number of integers in array A, and the number of operations. The next line contains n positive integers not greater than 100,000, the initial elements in array A. Each of the next q lines contains an operation. Each operation is formatted as a string having no more than 30 characters, with no space characters inside. All operations are guaranteed to be valid.


Warning: The dataset is large, better to use faster I/O methods.

Output 

For each query, print the minimum value (rather than index) in the requested range.

Sample Input 

7 56 2 4 8 5 1 4query(3,7)shift(2,4,5,7)query(1,4)shift(1,2)query(2,2)

Sample Output 

146



The Seventh Hunan Collegiate Programming Contest 
Problemsetter: Rujia Liu, Special Thanks: Yiming Li & Jane Alam Jan

运用线段树的查询区间最值和单点修改。

#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <cstring>#include <map>#include <string>#include <stack>#include <cctype>#include <vector>#include <queue>#include <set>using namespace std;//#define Online_Judge#define outstars cout << "***********************" << endl;#define clr(a,b) memset(a,b,sizeof(a))#define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)const int MAXN = 100000 + 50;const int maxw = 100 + 20;const int MAXNNODE = 1000000 +10;const long long LLMAX = 0x7fffffffffffffffLL;const long long LLMIN = 0x8000000000000000LL;const int INF = 0x7fffffff;const int IMIN = 0x80000000;#define eps 1e-8#define mod 1000000007typedef long long LL;const double PI = acos(-1.0);typedef double D;typedef pair<int , int> pi;struct Node{    int left;    int right;    int minx;};int n , q ;Node node[4*MAXN];/*最多需要分配的空间*/int number[MAXN];//向上更新void push_up(int pos){    node[pos].minx = min(node[pos<<1].minx , node[(pos<<1)+1].minx);/*向上更新当前点的信息*/}/*建立空的二叉树,初始化每个营地人数为0*/void buildTree(int left , int right , int pos){    node[pos].left = left;    node[pos].right = right;    if(left == right)    {        node[pos].minx = number[left];        return;    }    /*递归建立子树*/    int mid = (left+right)>>1;    buildTree(left , mid , pos<<1);    buildTree(mid+1 , right , (pos<<1)+1);    push_up(pos);}/*单点更新*/void update(int p , int d , int l , int r ,int pos){    if(l == r)    {        number[l] = d;        node[pos].minx = d;        return;    }    int m = (l + r) >> 1;    if(p <= m)update(p , d , l , m , pos << 1);    else update(p , d , m + 1 , r ,(pos << 1) + 1);    push_up(pos);}int query(int ql,int qr,int l,int r,int s){    if(ql <= l&&r <= qr)        return node[s].minx;    int m = (l + r)>>1,ans=INF;    if(ql <= m) ans = min(ans,query(ql , qr , l , m , s << 1));    if(qr > m) ans = min(ans,query(ql , qr , m + 1 , r , (s << 1) + 1));    return ans;}char s[35];vector<int> V , A;int main(){    //ios::sync_with_stdio(false);#ifdef Online_Judge    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);#endif // Online_Judge    while(scanf("%d%d", &n ,&q) == 2)    {        FORR(i , 1 , n)scanf("%d" , &number[i]);        buildTree(1 , n , 1);        while(q--)        {            scanf("%s" , s);            int len = strlen(s);            if(s[0] == 'q')            {                int a = 0;                int b = 0;                int i  = 4;                while(s[i] != ',')                {                    if(isdigit(s[i]))                    {                        a = a * 10 + s[i] -'0';                    }                    i++;                }                while(i < len)                {                    if(isdigit(s[i]))                    {                        b = b * 10 + s[i] - '0';                    }                    i++;                }                printf("%d\n" , query(a , b , 1 , n ,1));            }            else            {                int i = 4;                V.clear();                A.clear();                while(i < len)                {                    int a = 0;                    while(s[i] != ','&&s[i] != ')')                    {                        if(isdigit(s[i]))                        {                            a = a * 10 + s[i] - '0';                        }                        i++;                    }                    i++;                    V.push_back(a);                    A.push_back(number[a]);                }                int b = A[0];                A.erase(A.begin());                A.push_back(b);                FOR(k , 0 , V.size())update(V[k] , A[k] , 1 , n , 1);            }        }    }    return 0;}

UVA的第150题!Mark一下,继续加油!

原创粉丝点击