zoukankan      html  css  js  c++  java
  • Luogu 3332 [ZJOI2013]K大数查询

    BZOJ 3110

    很早就想写的试炼场题。

    不会整体二分啊呜呜呜,只能写写树套树。

    有一个trick就是外层使用一个权值线段树,把位置作为下标的线段树放在内层,这样子的话我们在查询$k$大的时候就可以直接在外层线段树上一边走一边二分。

    注意我们查询的是第$k$大不是第$k$小,所以我们在走的时候要观察右子树的权值和$k$的关系。

    内层可以动态开点防mle,注意在打标记下传的时候要先给左右儿子赋值。

    挺卡常的。

    时间复杂度$O(nlog^2n)$。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N = 5e4 + 5;
    
    int n, qn, mn, tot = 0;
    ll val[N];
    
    struct Querys {
        int type, l, r;
        ll k;
    } q[N];
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9'|| ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    namespace SegT {
        struct Node {
            int lc, rc, tag;
            ll sum;
        } s[N * 400];
        
        int root[N << 2], nodeCnt = 0;
        
        #define lc(p) s[p].lc
        #define rc(p) s[p].rc
        #define sum(p) s[p].sum
        #define tag(p) s[p].tag
        #define mid ((l + r) >> 1)
        
        inline void up(int p) {
            if(!p) return;
            sum(p) = sum(lc(p)) + sum(rc(p));
        }
        
        inline void down(int p, int l, int r) {
            if(!tag(p)) return;
            if(!lc(p)) lc(p) = ++nodeCnt;
            if(!rc(p)) rc(p) = ++nodeCnt;
            sum(lc(p)) += 1LL * tag(p) * (mid - l + 1), tag(lc(p)) += tag(p);
            sum(rc(p)) += 1LL * tag(p) * (r - mid), tag(rc(p)) += tag(p);
            tag(p) = 0;
        }
        
        void ins(int &p, int l, int r, int x, int y) {
            if(!p) p = ++nodeCnt;
            if(x <= l && y >= r) {
                ++tag(p);
                sum(p) += 1LL * (r - l + 1);
                return;
            }
            
            down(p, l, r);
            if(x <= mid) ins(lc(p), l, mid, x, y);
            if(y > mid) ins(rc(p), mid + 1, r, x, y);
            up(p);
        }
        
        ll getSum(int p, int l, int r, int x, int y) {
            if(!p) return 0LL;
            if(x <= l && y >= r) return sum(p);
            
            down(p, l, r);
            
            ll res = 0LL;
            if(x <= mid) res += getSum(lc(p), l, mid, x, y);
            if(y > mid) res += getSum(rc(p), mid + 1, r, x, y);
            return res;
        }
        
        void modify(int p, int l, int r, int x, int y, int v) {
            ins(root[p], 1, n, x, y);
            if(l == r) return;
            
            if(v <= mid) modify(p << 1, l, mid, x, y, v);
            else modify(p << 1 | 1, mid + 1, r, x, y, v);
        }
        
        int query(int p, int l, int r, int x, int y, ll k) {
            if(l == r) return l;
            
            ll now = getSum(root[p << 1 | 1], 1, n, x, y);
            if(now >= k) return query(p << 1 | 1, mid + 1, r, x, y, k);
            else return query(p << 1, l, mid, x, y, k - now);
        }
        
    } using namespace SegT;
    
    int main() {
        read(n), read(qn);
        for(int i = 1; i <= qn; i++) {
            read(q[i].type), read(q[i].l), read(q[i].r), read(q[i].k);
            if(q[i].type == 1) val[++tot] = q[i].k;
        }
        
        sort(val + 1, val + tot + 1);
        tot = unique(val + 1, val + 1 + tot) - val - 1;
        mn = tot;
        
        for(int i = 1; i <= qn; i++) {
            if(q[i].type == 1) {
                int v = lower_bound(val + 1, val + 1 + tot, q[i].k) - val;
                modify(1, 1, mn, q[i].l, q[i].r, v);
            } else printf("%lld
    ", val[query(1, 1, mn, q[i].l, q[i].r, q[i].k)]);
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    windows下mysql初始密码设置
    python生成简单的验证码
    python中HTMLParser简单理解
    Windows批处理(cmd/bat)常用命令小结
    文件结束的判断和结束符的理解
    交换机与路由器
    结构体字节对齐
    有(无)符号char型及其溢出问题
    kubernetes离线包安装教程
    kubernetes(K8S)快速安装与配置集群搭建图文教程
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9726625.html
Copyright © 2011-2022 走看看