倍增题目选做

LOJ 10120. 最敏捷的机器人

ST算法的模板题

#include <bits/stdc++.h>

using namespace std;

int read() {
    int x = 0, f = 1, ch = getchar();

    while ((ch < '0' || ch > '9') && ch != '-')
        ch = getchar();

    if (ch == '-')
        f = -1, ch = getchar();

    while (ch >= '0' && ch <= '9')
        x = (x << 3) + (x << 1) + ch - '0', ch = getchar();

    return x * f;
}

const int N = 1e5 + 5, logN = 17;
int f[N][logN + 5], g[N][logN + 5];

int32_t main() {
    int n = read(), k = read();

    for (int i = 1 ; i <= n ; i ++)
        f[i][0] = g[i][0] = read();

    for (int j = 1 ; (1 << j) <= n ; j ++)
        for (int i = 1; i + (1 << j) - 1 <= n ; i ++)
            f[i][j] = max(f[i][j - 1], f[ i + (1 << j - 1) ][j - 1]),
                      g[i][j] = min(g[i][j - 1], g[ i + (1 << j - 1) ][j - 1]);

    for (int i = 1, s = log2(k), t = k - (1 << s) ; i <= n - k + 1 ; i ++) {
        printf("%d %d\n", max(f[i][s], f[i + t][s]), min(g[i][s], g[i + t][s]));
    }

    return 0;
}

LuoguP1816 忠诚

ST算法的模板题

#include<bits/stdc++.h>

using namespace std;

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

const int N = 1e5+5;
int n , m , a[N] , log_2[N] = { -1 , } , f[N][20];

int getMin( int l , int r ){
    int s = log_2[ r - l + 1 ];
    return min( f[l][s] , f[ r - ( 1 << s ) + 1 ][s] );
}

int32_t main() {
    n = read() , m = read();
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    for( int i = 1 ; i <= n ; i ++ )
        f[i][0] = a[i] , log_2[i] = log_2[i>>1] + 1;
    for( int j = 1 ; ( 1 << j ) <= n ; j ++ )
        for( int i = 1 ; i + ( 1 << j ) - 1 <= n ; i ++ )
            f[i][j] = min( f[i][j-1] , f[ i + ( 1 << j-1 ) ][j-1] );
    for( int l , r ; m ; m -- )
        l = read() , r = read() , printf("%d " , getMin( l , r ) );
    return 0;
}

AcWing 109. 天才ACM

  1. 每次初始化 p=1,l=r
  2. 然后计算[l,r+p]的校验值,如果小于Tr+=p ,p*=2,否则p/=2
  3. 重复过程2,直到p=0此时的r就是对于l的最优解
#include<bits/stdc++.h>
#define int long long
using namespace std;

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

const int N = 5e5+5;
int a[N] , b[N];
int n , m , t , res;
int query( int l , int r ){
    if( r > n ) return 1e19;
    for( int i = l ; i <= r ; i ++ ) b[i] = a[i];
    sort( b + l , b + r + 1);
    int ans = 0;
    for( int i = l , j = r , t = 1 ; t <= m && i < j ; t ++ , i ++ , j -- )
        ans += ( b[i] - b[j] ) * ( b[i] - b[j] );
    return ans;
}

void solve(){
    n = read() , m = read() , t = read() , res = 0;
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    for( int l = 1 , r = 1 , p; l <= n ; l = r + 1 ){
        p = 1 , r = l;
        while( p ){
            if( query( l , r + p ) <= t ) r += p , p *= 2;
            else p /= 2;
        }
        res ++;
    }
    cout << res << "\n";
}

int32_t main() {
    for( int T = read(); T ; T -- )
        solve();
    return 0;
}
posted @ 2022-07-27 11:45  PHarr  阅读(27)  评论(0编辑  收藏  举报