标签:
题意:
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <fstream> using namespace std; const int maxn =100010; int RMQ[maxn<<2]; int str[maxn]; int N,M; char ctr[35]; int total[35],cnt; int build(int first,int second,int root) {//建树(初始化) if(first==second) { RMQ[root]=str[first]; str[first]=root;//记录原数组在线段树中的位置 return RMQ[root]; } if(first<second) { int L=root*2; return RMQ[root]=min(build(first,(first+second)/2,L),build((first+second)/2+1,second,L+1)); } return 10000000; } void updata(int x,int data) {//更新节点 RMQ[x]=data; int n=x/2; int key; while(n) { RMQ[n]=min(RMQ[n*2],RMQ[n*2+1]); n=n/2; } } int query(int a,int b,int root,int l,int r) {//查询 [l,r]是要查询的区间,[a,b]是root维护的区间 if(a>r || b<l) return 10000000; if(l<=a && b<=r) return RMQ[root]; else { int Left=(a+b)/2; if(Left>=r) return query(a,Left,root*2,l,r); if(Left<l) return query(Left+1,b,root*2+1,l,r); return min(query(a,Left,root*2,l,r),query(Left+1,b,root*2+1,l,r)); } return 1000000; } void solve() { int len=strlen(ctr); cnt=0; memset(total,0,sizeof(total)); for(int i=6; i<len; i++) { if(ctr[i]==')') break; if(ctr[i]==',') { cnt++; continue; } int t=ctr[i]-'0'; total[cnt]=t+total[cnt]*10; } if(ctr[0]=='q') printf("%d\n",query(1,N,1,total[0],total[1])); else { int key=RMQ[str[total[0]]]; for(int i=cnt; i>=0; i--) { int z=str[total[i]]; int q=RMQ[z]; updata(z,key); key=q; } } } int main() { scanf("%d%d",&N,&M); for(int i=1; i<=N; i++) scanf("%d",&str[i]); build(1,N,1); for(int i=0; i<M; i++) { scanf("%s",ctr); solve(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
线段树模板(区间最小值优化 版) (RMQ with Shifts)
标签:
原文地址:http://blog.csdn.net/yu_zhi_bo_zhi_shui/article/details/47802859