zoukankan      html  css  js  c++  java
  • [Luogu] 列队

    https://www.luogu.org/problemnew/show/P3960

    如果 x = 1,相当于维护一条链,每次取出第 k 个数放在序列末尾
    假设有 n + m + q 个位置,每个位置有数为 1 ,没有数为 0,
    取出后不前移,那么第 k 个数就是第 k 个 1 的位置
    初始时 1 ~ n + m - 1 为 1,其他位置为 0,
    用线段树维护区间和即可
    类似对于这道题把每行看做一条链,最后一列看做一条链
    一次操作可以看成对两条链的操作
    套用上面的方法即可
    注意要动态开点

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 3e5 + 10;
    
    int n, m, Q, N_;
    int size[N * 20], lson[N * 20], rson[N * 20];
    int root[N], jdjs;
    int ins[N];
    int now_root;
    
    #define LL long long
    
    LL val[N * 20];
    LL Ans1;
    
    #define gc getchar()
    
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    int Calc_size(int l, int r) {
        if(now_root != n + 1) {
            if(r <= m - 1) return r - l + 1;
            else {
                if(l <= m - 1) return (m - 1) - l + 1;
                else return 0;
            }
        } else {
            if(r <= n) return r - l + 1;
            else {
                if(l <= n) return n - l + 1;
                else return 0;
            }
        }
        
    }
    
    void Sec_A(int l, int r, int & jd, int x) {
        if(!jd) {
            jd = ++ jdjs;
            size[jd] = Calc_size(l, r);
            if(l == r) {
                if(now_root <= n) val[jd] = (LL) 1ll * (now_root - 1) * m + l;    
                else val[jd] = (LL) 1ll * l * m;
            }
        }
        size[jd] --;
        if(l == r) {Ans1 = val[jd]; return ;}
        int mid = (l + r) >> 1;
        if((!lson[jd] && x <= mid - l + 1) || x <= size[lson[jd]]) Sec_A(l, mid, lson[jd], x);
        else {
            if(!lson[jd]) x -= (mid - l + 1);
            else x -= size[lson[jd]];
            Sec_A(mid + 1, r, rson[jd], x);
        }
    }
    
    void Ins(int l, int r, int & jd, int whe, LL Num) {
        if(!jd) {
            jd = ++ jdjs;
            size[jd] = Calc_size(l, r);
            if(l == r) val[jd] = Num;
        }
        size[jd] ++;
        if(l == r) return ;
        int mid = (l + r) >> 1;
        if(whe <= mid) Ins(l, mid, lson[jd], whe, Num);
        else Ins(mid + 1, r, rson[jd], whe, Num);
    }
    
    int main() {
        n = read(), m = read(), Q = read();
        N_ = max(n, m) + Q;
        while(Q --) {
            int x = read(), y = read();
            if(y == m) now_root = n + 1, Sec_A(1, N_, root[now_root],x);
            else now_root = x, Sec_A(1, N_, root[now_root], y);
            cout << Ans1 << endl;
            now_root = n + 1; Ins(1, N_, root[n + 1], n + (++ ins[n + 1]), Ans1);
            if(y != m) {
                now_root = n + 1; Sec_A(1, N_, root[now_root], x);
                now_root = x; Ins(1, N_, root[x], m - 1 + (++ ins[x]), Ans1);
            }
        }
        return 0;
    }
  • 相关阅读:
    【转】 Android代码混淆之混淆规则
    【转】java虚拟机机制总结
    【转】图解 HTTP协议/IIS 原理及ASP.NET运行机制浅析
    【转】Android 消息机制
    Android-eclipse-NDK&JNI
    【转】大型网站系统架构的演化
    【转】Android开发必知--WebView加载html5实现炫酷引导页面
    【转】Java虚拟机详解----GC算法和种类
    网页中缩略图的意义
    网页开关灯效果
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8985187.html
Copyright © 2011-2022 走看看