zoukankan      html  css  js  c++  java
  • CF1032G Chattering

    CF1032G Chattering

    容易发现,这道题用倍增。(秒掉题目算法,被实现卡掉。。。)
    再撕烤,是区间跳区间,那么其实更新的是端点,那么维护什么就很显然。
    用ST表维护一个从当前点开始 (2^i) 秒能跳到的左右端点,再用一个ST表维护一个区间内能跳到的左右的最远点,然后用后者更新前者。
    最后一直倍增跳就完了。
    时空 (O(n log n))

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 3e5+10;
    
    ll N, M, Log[MAXN], val[MAXN], lb[MAXN], rb[MAXN], lt[21][MAXN], rt[21][MAXN];
    
    struct st_biao {
        ll st[21][MAXN], v[MAXN], type;
        ll Max(ll x, ll y) {return (v[x] < v[y]) ? y : x;}
        void build(ll *now, ll n, ll _type) {
            type = _type;
            for (ll i = 1; i <= n; i++) st[0][i] = i, v[i] = type * now[i];
            for (ll i = 1; i <= Log[n]; i++)
                for (ll j = 1; j + (1LL << i) - 1 <= n; j++)
                    st[i][j] = Max(st[i-1][j], st[i-1][j+(1LL << (i-1))]);
        }
        ll qmin(ll l, ll r) {
            ll dis = Log[r - l + 1];
            return Max(st[dis][l], st[dis][r - (1LL << dis) + 1]);
        }
    } stl, str;
    
    int main() {
        scanf("%lld", &N);
        for (ll i = 2; i <= 3 * N; i++) Log[i] = Log[i>>1] + 1;
        for (ll i = 1; i <= N; i++)
            scanf("%lld", val+i), val[i+N*2] = val[i+N] = val[i];
        if (N == 1) {
        	puts("0");
    		return 0;
    	}
        for (ll i = 1; i <= 3*N; i++) {
            lb[i] = max(1LL, i - val[i]);
            rb[i] = min(3*N, i + val[i]);
        }
        for (ll i = 0; i <= Log[3*N]; i++) rt[i][3*N] = 3*N, lt[i][1] = 1;
        for (ll i = 1; i <= 3 * N; i++) {
            lt[0][i] = lb[i];
            rt[0][i] = rb[i];
        }
        stl.build(lt[0], 3*N, -1), str.build(rt[0], 3*N, 1);
        for (ll i = 1; i <= Log[3*N]; i++) {
            for (ll j = 1; j <= 3 * N; j++) {
                ll pl = stl.qmin(lt[i-1][j], rt[i-1][j]);
                ll pr = str.qmin(lt[i-1][j], rt[i-1][j]);
                lt[i][j] = min(lt[i-1][pl], lt[i-1][pr]);
                rt[i][j] = max(rt[i-1][pl], rt[i-1][pr]);
            }
        }
        for (ll j = N+1; j <= 2*N; j++) {
            ll ans = 0;
            ll lk = j, rk = j;
            for (ll i = Log[3*N]; ~i; i--) {
                if (max(rt[i][lk], rt[i][rk]) - min(lt[i][lk], lt[i][rk]) + 1 >= N) continue;
                ll nl = stl.qmin(lt[i][lk], rt[i][rk]);
                ll nr = str.qmin(lt[i][lk], rt[i][rk]);
                lk = nl, rk = nr;
                ans += (1LL << i); 
            }
            printf("%lld ", ans + 1);
        }
        return 0;
    }
    
  • 相关阅读:
    分母为0一定会抛异常吗?
    [译]Zookeeper的优点与局限性
    明明有class为什么还是报ClassNotFoundException?
    广告倒排索引架构与优化
    KafkaProducer源码分析
    Kafka服务端之网络连接源码分析
    Sublime常用快捷键
    sublime主题设置
    Sublime前端插件
    安装软件,更新软件,删除软件
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/13904452.html
Copyright © 2011-2022 走看看