tzoj4325 RMQ with Shifts(线段树+单点更新+区间查询)

时间:2019-09-19
本文章向大家介绍tzoj4325 RMQ with Shifts(线段树+单点更新+区间查询),主要包括tzoj4325 RMQ with Shifts(线段树+单点更新+区间查询)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte

描述

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}.  

输入

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.

输出

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

样例输入

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)

样例输出

1
4
6

每一行操作语句不超过30个字符,除去操作query,shift,(,),真正涉及到操作数据的并不多

查询时查询区间最小值,更新时进行单点更新,直接更改每一个的值

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int MAXN=1e5+5;
 6 int a[MAXN],st[MAXN<<2],INF=0x3f3f3f3f;
 7 
 8 inline int read(){
 9     int x=0,f=1;
10     char ch=getchar();
11     while(ch<'0'||ch>'9'){
12         if(ch=='-')
13             f=-1;
14         ch=getchar();
15     }
16     while(ch>='0'&&ch<='9'){
17         x=(x<<1)+(x<<3)+(ch^48);
18         ch=getchar();
19     }
20     return x*f;
21 }
22 
23 void pushup(int root){
24     st[root]=min(st[root<<1],st[root<<1|1]);
25 }
26 
27 void build(int l,int r,int root){
28     if(l==r){
29         st[root]=a[l];
30         return;
31     }
32     int mid=(l+r)>>1;
33     build(l,mid,root<<1);
34     build(mid+1,r,root<<1|1);
35     pushup(root);
36 }
37 
38 void update(int pos,int val,int l,int r,int root){
39     if(pos<=l&&r<=pos){
40         st[root]=val;
41         return;
42     }
43     int mid=(l+r)>>1;
44     if(pos<=mid)update(pos,val,l,mid,root<<1);
45     else update(pos,val,mid+1,r,root<<1|1);
46     pushup(root);
47 }
48 
49 int query(int L,int R,int l,int r,int root){
50     if(L<=l&&r<=R)return st[root];
51     int mid=(l+r)>>1,res=INF;
52     if(L<=mid)res=min(res,query(L,R,l,mid,root<<1));
53     if(R>mid)res=min(res,query(L,R,mid+1,r,root<<1|1));
54     pushup(root);
55     return res;
56 }
57 
58 int main(){
59     int n,q,val[35];
60     char c,head;
61     n=read(),q=read();
62     for(int i=1;i<=n;i++){
63         a[i]=read();
64     }
65     build(1,n,1);
66     while(q--){
67         int k=0;
68         head=getchar();
69         while(c=getchar(),c!='(');
70         while(1){
71             scanf("%d",&val[k++]);
72             c=getchar();
73             if(c==')')break;
74         }
75         if(head=='q'){
76             printf("%d\n",query(val[0],val[1],1,n,1));
77         }
78         else if(head=='s'){
79             int bef=query(val[0],val[0],1,n,1),v;
80             for(int i=0;i<k-1;i++){
81                 v=query(val[i+1],val[i+1],1,n,1);
82                 update(val[i],v,1,n,1);
83             }
84             update(val[k-1],bef,1,n,1);
85         }
86         getchar();
87     }
88 }

原文地址:https://www.cnblogs.com/ChangeG1824/p/11552299.html