zoukankan      html  css  js  c++  java
  • 【LOJ】#2495. 「AHOI / HNOI2018」转盘

    题面

    题解

    考虑我肯定是从一个人出发,开始依次标记,而不会跳过某个人,因为如果我跳过了,那么我之后回来还需要标记它,比不上我等完它再一直走到最后(因为多了走一圈之后走回它的代价)

    我们倍长整个序列,我们要求的就是
    (Min_{i = 1}^{n}{Max_{j = i}^{i + n - 1}{T_j - j + i + N - 1}})
    显然(j)越大这个值越小,那么又可以转化成
    (Min_{i = 1}^{n}{Max_{j = i}^{2n}{T_j - j + i + N - 1}})
    (A_i = T_i - i)
    那么我们要求的就是
    (Min_{i = 1}^{n}{Max_{j = i}^{2n}{A_j} + i} + N - 1)
    我们考虑维护一个(MAXV)(A_i)的区间最大值,一个(VAL)为这个区间(Min_{i = L}^{Mid} {Max_{j = i}^{R}{A_j} + i})
    然后(Query(u,v))表示查询(u)这个区间的答案,后面区间的最大值是(v)
    如果(v <= MAXV_{rc})那么这个区间维护的(VAL)就是左区间的值,到右区间继续查找即可
    否则右区间的最小贡献就是(mid + 1 + v),然后递归到左区间去查即可

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define mp make_pair
    #define MAXN 100005
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
        	if(c == '-') f = -1;
        	c = getchar();
        }
        while(c >= '0' && c <= '9') {
        	res = res * 10 + c - '0';
        	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {putchar('-');x = -x;}
        if(x >= 10) {
        	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    int N,M,P;
    int a[MAXN * 2];
    multiset<int> S;
    struct node {
        int L,R,val,maxv;
    }tr[MAXN * 4];
    void update(int u);
    void build(int u,int l,int r);
    int Query(int u,int suf);
    void build(int u,int l,int r) {
        tr[u].L = l;tr[u].R = r;
        if(l == r) {
            tr[u].maxv = a[l];
            tr[u].val = a[l] + l;
            return ;
        }
        int mid = (l + r) >> 1;
        build(u << 1,l,mid);
        build(u << 1 | 1,mid + 1,r);
        update(u);
    }
    void update(int u) {
        tr[u].maxv = max(tr[u << 1].maxv,tr[u << 1 | 1].maxv);
        tr[u].val = Query(u << 1,tr[u << 1 | 1].maxv);
    }
    int Query(int u,int suf) {
        if(tr[u].L == tr[u].R) return tr[u].L + max(tr[u].maxv,suf);
        int mid = (tr[u].L + tr[u].R) >> 1;
        if(suf <= tr[u << 1 | 1].maxv) return min(tr[u].val,Query(u << 1 | 1,suf));
        else return min(mid + 1 + suf,Query(u << 1,suf));
    }
    void Change(int u,int pos) {
        if(tr[u].L == tr[u].R) {
            tr[u].val = a[pos] + pos;
            tr[u].maxv = a[pos];
            return;
        }
        int mid = (tr[u].L + tr[u].R) >> 1;
        if(pos <= mid) Change(u << 1,pos);
        else Change(u << 1 | 1,pos);
        update(u);
    }
    void Init() {
        read(N);read(M);read(P);
        for(int i = 1 ; i <= N ; ++i) {
            read(a[i]);a[i + N] = a[i];
            a[i] -= i;a[i + N] -= i + N;
            S.insert(a[i + N]);
        }
        build(1,1,N);
    }
    void Solve() {
        int lastans = Query(1,*(--S.end())) + N - 1;
        int x,y;
        out(lastans);enter;
        for(int i = 1 ; i <= M ; ++i) {
            read(x);read(y);
            if(P) {x ^= lastans;y ^= lastans;}
            a[x] = y - x;
            S.erase(S.find(a[x + N]));
            a[x + N] = y - x - N;
            S.insert(a[x + N]);
            Change(1,x);
            lastans = Query(1,*(--S.end())) + N - 1;
            out(lastans);enter;
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        Solve();
    }
    
  • 相关阅读:
    RxJava Android(RxAndroid) 开发全家桶
    Android Retrofit RxJava实现缓存
    Android Touch事件传递机制详解 下
    Android Touch事件传递机制详解 上
    Android Framework 记录之二
    XMind 8 Update 7 Pro 激活码
    leetcode 2-> Add Two Numbers
    leetcode 1 -> Two Sum
    leetcode 3-> Longest Substring Without Repeating Characters
    Python enumerate() 函数
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9975265.html
Copyright © 2011-2022 走看看