[JSOI2008] 最大數 (ST表)

Yorg發表於2024-10-02

演算法

觀察到插入都在末尾進行
考慮逆向ST表

程式碼

#include <bits/stdc++.h>
const int MAXSIZE = 2e5 + 20;
#define int long long

int Time, D;

int t = 0;

/*反向st表方便處理末尾的插入*/
class reverse_ST
{
    private:
        int Max[MAXSIZE][20];

    public:
        int NowSize;

        void init()
        {
            memset(Max, 0, sizeof(Max));
            NowSize = 0;
        }

        void insert(int x)
        {
            Max[++NowSize][0] = x;
            for(int i = 1; NowSize - (1 << i) >= 0; i++)
            {
                Max[NowSize][i] = std::max(Max[NowSize][i - 1], Max[NowSize - (1 << (i - 1))][i - 1]);
            }
        }

        int find(int L, int R) 
        {
            int Length = R - L + 1;
            int k = log2(Length);

            return std::max(Max[R][k], Max[L + (1 << (k)) - 1][k]);
        }
}ST;

void solve()
{
    char type;
    ST.init();
    while(Time--)
    {
        std::cin >> type;
        if(type == 'A')
        {
            int x;
            scanf("%lld", &x);
            ST.insert((x + t) % D);
        }else{
            int L;
            scanf("%lld", &L);
            int ans = ST.find(ST.NowSize - L + 1, ST.NowSize);
            printf("%lld\n", ans);
            t = ans;
        }
    }
}

signed main()
{

    scanf("%lld %lld", &Time, &D);

    solve();
    return 0;
}

總結

程式碼

注意ST表的查詢方式為

int Length = R - L + 1;
int k = log2(Length);

return std::max(Max[R][k], Max[L + (1 << (k)) - 1][k]);

思路

正難則反

相關文章