CSU 1110線段樹

C - RMQ with Shifts
Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Appoint description: 

Description

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=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(i1, i2, i3, …, ik) (i1<i2<...<ik, k>1): we do a left “circular shift” of A[i1], A[i2], …, A[ik]. 
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}.

Input

There will be only one test case, beginning with two integers n, q (1<=n<=100,000, 1<=q<=120,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 5
6 2 4 8 5 1 4
query(3,7)
shift(2,4,5,7)
query(1,4)
shift(1,2)
query(2,2)

Sample Output

1
4
6 
152ms
分析:題目中說了a string having no more than 30 characters ,說明每次操作數據量比較小,可以用線段樹直接搞,寫代碼的時候有很多細節要注意,不然就各種wrong,
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;

const int MAXN=100010;

int n,m;
int a[MAXN];

int shift[40];
char s[50];

struct node
{
  int l,r;
  int minn;
}st[MAXN*4];

void build(int v,int l,int r)
{
    st[v].l=l;
    st[v].r=r;
    if(l==r)
    {
      st[v].minn=a[l];
      return ;
    }
    int mid=(l+r)/2;
    build(2*v,l,mid);
    build(2*v+1,mid+1,r);
    st[v].minn=min(st[2*v].minn,st[2*v+1].minn);
}

void update(int v,int id,int key)
{
    if(st[v].l==st[v].r&&st[v].l==id)
    {
       st[v].minn=key;
       return ;
    }
    int mid=(st[v].l+st[v].r)/2;
    if(id<=mid)
        update(2*v,id,key);
    else
        update(2*v+1,id,key);
    st[v].minn=min(st[2*v].minn,st[2*v+1].minn);
}

int RMQ(int v,int l,int r)
{
   if(st[v].l==l &&st[v].r==r)
        return st[v].minn;
   int mid=(st[v].l+st[v].r)/2;
   if(r<=mid)
      return RMQ(2*v,l,r);
   else if(l>mid)
       return RMQ(2*v+1,l,r);
   else
   {
       int t1=RMQ(2*v,l,mid);
       int t2=RMQ(2*v+1,mid+1,r);
       return min(t1,t2);
   }
}

int main()
{
   while(scanf("%d%d",&n,&m)!=EOF)
   {
       for(int i=1;i<=n;i++)scanf("%d",&a[i]);
       build(1,1,n);
       //cout<<st[1].minn<<endl;
       while(m--)
       {
           scanf("%s",s);
           if(s[0]=='q')
           {
               int l=0,r=0,i,j;
               for(i=6;s[i]!=',';i++)l=l*10+(s[i]-'0');
               for(j=i+1;s[j]!=')';j++)r=r*10+(s[j]-'0');

              // cout<<l<<" "<<r<<endl;
               printf("%d\n",RMQ(1,l,r));
           }
           else
           {
               int base=0,ct=0;
               for(int i=6;s[i]!=')';)
               {
                   if(s[i]==',')
                   {
                      i++;
                      shift[++ct]=base;
                      base=0;
                      continue;
                   }
                   base=base*10+(s[i]-'0');
                   i++;
               }
               shift[++ct]=base;

               int tmp=a[shift[1]];
               for(int i=2;i<=ct;i++)
               {
                   a[shift[i-1]]=a[shift[i]];
               }
               a[shift[ct]]=tmp;
               for(int i=1;i<=ct;i++)update(1,shift[i],a[shift[i]]);
            }
       }

   }
   return 0;
}


發佈了244 篇原創文章 · 獲贊 17 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章