给定一个长度为n的序列A,可以对其进行一下两种操作:
1、query (L, R) 查询区间[L,R]的最小值
2、shift(i1, i2, i3,..., ik)(i1 < i2 < ... < ik, k > 1) 把元素A[i1],A[i2],…,A[ik]循环移动
区间最小值查询+单点修改。。。水题。。。。
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define MAXN 100005 #define lson l,m,s<<1 #define rson m+1,r,s<<1|1 #define INF 0x7fffffff int minv[MAXN<<2],val[MAXN]; vector<int> V,A; void PushUp(int s) { minv[s]=min(minv[s<<1],minv[s<<1|1]); } void build(int l,int r,int s) { if(l==r) { scanf("%d",&val[l]); minv[s]=val[l]; return; } int m=(l+r)>>1; build(lson); build(rson); PushUp(s); } void update(int p,int d,int l,int r,int s) { if(l==r) { val[l]=d; minv[s]=d; return; } int m=(l+r)>>1; if(p<=m) update(p,d,lson); else update(p,d,rson); PushUp(s); } int query(int ql,int qr,int l,int r,int s) { if(ql<=l&&r<=qr) return minv[s]; int m=(l+r)>>1,ans=INF; if(ql<=m) ans=min(ans,query(ql,qr,lson)); if(qr>m) ans=min(ans,query(ql,qr,rson)); return ans; } int main(void) { int n,m,len; char s[45]; while(~scanf("%d%d",&n,&m)) { build(1,n,1); while(m--) { int a,b; scanf("%s",s); len=strlen(s); if(s[0]=='q') { a=0; 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(val[a]); } int b=A[0]; A.erase(A.begin()); A.push_back(b); for(int i=0; i<V.size(); i++) update(V[i],A[i],1,n,1); } } } return 0; }