zoukankan      html  css  js  c++  java
  • P4425 [HNOI/AHOI2018]转盘

    P4425 [HNOI/AHOI2018]转盘

    这次算是对楼房重建问题有一个初步理解了。大体就是先处理一个区间对另一个区间的影响,再处理另一个区间的影响。对于这个题:

    [displaystyle egin{array}{l} extbf{def:} ext{ask} (node, val) \ qquad extbf{if} (node ext{is leafy node}) \ qquad qquad extbf{return} [t[node].maxn > val] * inf + val + t[node].l \ qquad extbf{else} \ qquad qquad extbf{if} (t[node << 1 | 1].maxn > val) \ qquad qquad qquad extbf{return} min( ext{ask}(node << 1 | 1, val), t[node].tr) \ qquad qquad extbf{else} \ qquad qquad qquad extbf{return} ext{ask}(node << 1, val) \ qquad qquad extbf{endif.} \ qquad extbf{endif.} \ extbf{enddef.} end{array} ]

    就是维护一个后缀单调栈。复杂度 (O(n log^2n))

    下面是这个题的推式子。


    可以发现,这个题就是先在某个地方停一会,然后不停下脚步走一圈。先断开环转化为 (2N)

    那么考虑对于一个地方 (i) 其出现时间为 (t_i)。假定从 (j) 出发,在 (j) 停下时间至少为 (t_i - (i - j)) 那么答案就是 (displaystyle min_{j=1}^N{ max_{i=j}^{j+N-1}{ t_i - i } + j} + N - 1)(N-1) 是走完这一圈。

    考虑 (t_i = t_{i+N})(i lt i+N) 所以 (t_i - i gt t_{i+N} - (i+N)) 。那么转化为 (displaystyle min_{j=1}^N{ max_{i=j}^{2N}{ t_i - i } + j} + N - 1)

    可以发现,对于 (t_i - i) 固定,直到前面一个大于它的 (t_j - j),答案永远由他决定,且答案为 (t_i - i + j + 1)。所以我们可以考虑单调栈维护 (t_i - i)

    假定单调栈元素为 (st_i),设 (st_0 = 0)(st_{bound-1} lt N le st_{bound})

    (displaystyle ans = min_{i=1}^{bound}(t_{st_i}- st_i + st_{i-1}) + N) 这题就维护一下 (t_i-i) 的单调栈就好了。

    因为 (i lt bound)(st_{i} gt N) 所以,这些最大值就是 ([1, N]) 里的最大值 (-N)。所以只需要维护 ([1, N])。最后在 ([1, N]) 上二分到位置之后加上长度就完了。

    /*
        Name:
        Author: Gensokyo_Alice
        Date:
        Description:
    */
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #include <ctime>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = (1LL << 20) + 10, INF = 0x3f3f3f3f3f3f3f3f;
    
    ll N, M, P, lst, val[MAXN];
    struct nod {
        ll l, r, maxn, tr; 
        nod (ll _l = 0, ll _r = 0, ll _maxn = 0, ll _tr = 0): l(_l), r(_r), maxn(_maxn), tr(_tr) {};
    } t[MAXN];
    
    void build(ll, ll, ll);
    void ins(ll, ll, ll);
    ll ask(ll, ll);
    void pushup(ll); 
    
    int main() {
        scanf("%lld%lld%lld", &N, &M, &P);
        for (ll i = 1; i <= N; i++) scanf("%lld", val+i);
        build(1, 1, N); printf("%lld
    ", lst = ask(1, t[1].maxn - N) + N);
        for (ll i = 1, x, y; i <= M; i++) {
            scanf("%lld%lld", &x, &y);
            if (P) x ^= lst, y ^= lst;
            val[x] = y; ins(1, x, y);
            printf("%lld
    ", lst = ask(1, t[1].maxn - N) + N);
        }
        return 0;
    }
    
    void build(ll node, ll l, ll r) {
        t[node] = nod(l, r);
        if (l == r) {t[node].maxn = (val[l] - l); return;}
        ll mid = (l + r) >> 1;
        build(node << 1, l, mid);
        build(node << 1 | 1, mid + 1, r);
        pushup(node);
    }
    
    void pushup(ll node) {
        t[node].maxn = max(t[node << 1].maxn, t[node << 1 | 1].maxn);
        t[node].tr = ask(node << 1, t[node << 1 | 1].maxn);
    }
    
    ll ask(ll node, ll pos) {
        if (t[node].l == t[node].r) return t[node].maxn > pos ? pos + t[node].l : INF;
        if (t[node << 1 | 1].maxn > pos) return min(t[node].tr, ask(node << 1 | 1, pos));
        else return ask(node << 1, pos);
    }
    
    void ins(ll node, ll pos, ll v) {
        if (t[node].l == pos && t[node].r == pos) {t[node].maxn = v - pos; return;}
        ll mid = (t[node].l + t[node].r) >> 1;
        if (pos <= mid) ins(node << 1, pos, v);
        else ins(node << 1 | 1, pos, v);
        pushup(node);
    }
    
  • 相关阅读:
    python-pandas
    iOS7程序内部如何打开评分页面
    iOS 7 UITableview 在Plain模式下 设置背景颜色无效
    Xcode5 运行程序 提示IOS 模拟器未能安装此应用程序
    解决 iOS7 通过tag 找不到 UITableViewCell 的子控件
    Java数据库编程及Java XML解析技术
    JavaI/O 系统
    Java图形用户界面编程
    Java中枚举的使用
    Java集合框架
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/14284955.html
Copyright © 2011-2022 走看看