树状数组求最大值 (RMQ with Shifts)
Posted mthoutai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组求最大值 (RMQ with Shifts)相关的知识,希望对你有一定的参考价值。
代码:
#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; }
以上是关于树状数组求最大值 (RMQ with Shifts)的主要内容,如果未能解决你的问题,请参考以下文章
UVa 12299 RMQ with Shifts(移位RMQ)
HDU 1754 - I Hate It & UVA 12299 - RMQ with Shifts - [单点/区间修改区间查询线段树]