zoukankan      html  css  js  c++  java
  • 树状数组求最大值 (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
    ",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;
    }
    


  • 相关阅读:
    hh
    SDUT 3923 打字
    最短路
    阶乘后面0的个数(51Nod 1003)
    大数加法
    Biorhythms(中国剩余定理)
    usaco-5.1-theme-passed
    usaco-5.1-starry-passed
    usaco-5.1-fc-passed
    usaco-4.4-frameup-passed
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7224737.html
Copyright © 2011-2022 走看看