树状数组求最大值 (RMQ with Shifts)

来源:互联网 发布:阿里云域名未备案 编辑:程序博客网 时间:2024/06/05 16:40

代码:

#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;}


0 0
原创粉丝点击