C-RMQ with ShiftsTime
limit:MS
Memory Limit:131072KB
64bit IO Format:%lld &%llu SubmitStatusPracticeCSU 1110Appoint Description:System Crawler (2015-03-10)
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 was no longer static:we need to support another operation shift (I1, I2, i3, ..., ik) (i1<i2& Lt;...<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 (yields) {8, 6, 4, 5, 4, 1, 2}.
Input
There be is only one test case, beginning with the 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 isn't 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 has no more than than characters, with no space characters inside. All operations is 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 2 4 8 5 1 4query (3,7) Shift (2,4,5,7) query (1,4) shift (2,2)
Sample Output
152ms
Analysis: The topic said a string has no more than characters, indicating that each operation data volume is small, you can use line tree directly, write code when there are a lot of details to pay attention to, otherwise all kinds of 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;}
CSU 1110 Segment Tree