代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; const int Max=200010; int RMQ[Max+10]; int total[Max]; int sum[35]; int N,M,cnt; char ctr[35]; int bit(int x) {//每一个下标管辖的范围 return x&(-x); } int query(int first,int second) {//查询 int res=total[second]; while(first<=second) { int key=bit(second); if(second-key>=first) { if(res>RMQ[second]) res=RMQ[second]; second=second-key; } else { if(res>total[second]) res=total[second]; second--; } } return res; } int updata(int x) {//更新x位置节点 for(int i=x;i<=N;i+=bit(i)) { RMQ[i]=total[i];//利用原数组来更新树状数组 for(int j=1;j<bit(i);j<<=1) {//这个是重点又一次扫描i节点所管辖的区间 RMQ[i]=min(RMQ[i],RMQ[i-j]); } } } void solve() { int len=strlen(ctr); cnt=0; memset(sum,0,sizeof(sum)); for(int i=6; i<len; i++) { if(ctr[i]==')') break; if(ctr[i]==',') { cnt++; continue; } int t=ctr[i]-'0'; sum[cnt]=t+sum[cnt]*10; } if(ctr[0]=='q') printf("%d\n",query(sum[0],sum[1])); else { int key=total[sum[0]]; for(int i=cnt; i>=0; i--) { int q=total[sum[i]]; total[sum[i]]=key;//先更新原数组 updata(sum[i]); key=q; } } } int main() { scanf("%d%d",&N,&M); for(int i=1;i<=N;i++) { scanf("%d",&total[i]); updata(i); } for(int i=0;i<M;i++) { scanf("%s",ctr); solve(); } return 0; }