ST Table

1.倍增

#include <iostream>

const int N = 100000 + 5000;
const int M = 21;

int a[N];
int t[N];

int n;

int f[N][M];//从第i站转车2的j次方到的站
int g[N][M];//从第i站专车2的j次方到的站用的时间

void init()
{
    for (int i = 1 ; i <= n ; i ++)
    {
        f[i][0] = a[i];
        g[i][0] = t[i];
    }//2的0次方 
    for (int i = 1 ; i <= 20; i ++)
    {
        for (int j = 1 ; j <= n ; j ++)
        {
            f[j][i] = f[f[j][i - 1]][i - 1];//先跳一半,再跳一半 
            g[j][i] = g[j][i - 1] + g[f[j][i - 1]][i - 1];//前一段的时间加上后一段 
        }
    }
}

void solve()
{
    int m;
    std :: cin >> m;
    int r = 1;//从1号站出发
    int time = 0;//时间
    for (int i = 20; i >= 0 ; i --)//移动2的i次方站 
    {
        if ((1 << i) <= m)
        {
            time += g[r][i];//从r出发移动2的j次方站所用的时间 
            r = f[r][i];//从r出发移动2的i次方站
            m -= (1 << i);//移动
            if (m == 0) break;//完了 
        }
    }
    std :: cout << r << " " << time << "\n";
}

int main()
{
    std :: cin >> n;
    for (int i = 1 ; i <= n ; i ++)
    {
        std :: cin >> a[i] >> t[i];
    }
    int m;
    std :: cin >> m;
    init();//初始化 
    while (m --) solve();
}

### 区间最大值和最小值

```cpp
#include 

const int N = 100005;

int h[N];
int n;

int f[N][21];//从i开始2的j次方个数最大值
int g[N][21];//从i开始2的j次方个数最小值
int lg[N];

void init()
{
    for (int i = 1 ; i <= n ; i ++) 
    {
        f[i][0] = h[i];
        g[i][0] = h[i];
    }
    for (int i = 1 ; i <= 20 ; i ++)
    {
        for (int j = 1 ; j + (1 << i) -1 <= n; j ++)
        {
            f[j][i] = std :: max(f[j][i - 1],f[j + (1 << (i - 1))][i - 1]);
            g[j][i] = std :: min(g[j][i - 1],g[j + (1 << (i - 1))][i - 1]);
        }
    }
    lg[1] = 0;
    for (int i = 2 ; i <= n ; i ++)
    {
        lg[i] = lg[i / 2] + 1;
    }
}

int querymax(int l,int r)
{
    int s = lg[r - l + 1];
    return std :: max(f[l][s],f[r-(1 << s) + 1][s]);
}

int querymin(int l,int r)
{
    int s = lg[r - l + 1];
    return std :: min(g[l][s],g[r-(1 << s) + 1][s]);
}

void solve()
{
    int l,r;
    std :: cin >> l >> r;
    int ans = querymax(l,r) - querymin(l,r);
    std :: cout << ans << "\n";
    //std :: cout <<  querymax(l,r) << " " << querymin(l,r) << "\n";
}

int main()
{   int t;
    std :: cin >> n;
    std :: cin >> t;
    for (int i = 1 ; i <= n ; i ++)
    {
        std :: cin >> h[i];
    }
    init();

    while (t --)solve();
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇