zoukankan      html  css  js  c++  java
  • [ZJOI 2013] K大数查询

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=3110

    [算法]

             整体二分 + 线段树

             时间复杂度 : O(NlogN ^ 2)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 500010
    typedef long long ll;
    typedef long double ld;
    
    struct query
    {
        int type , a , b;
        ll c;
        int id;
    } q[MAXN];
    
    int n , m;
    int ans[MAXN];
    
    struct Segment_Tree
    {
        ll cnt[MAXN << 4] , tag[MAXN << 4];
        Segment_Tree()
        {
            memset(cnt , 0 , sizeof(cnt));
        }
        inline void pushdown(int index , int l , int r)
        {
            int mid = (l + r) >> 1;
            cnt[index << 1] += (mid - l + 1) * tag[index];
            cnt[index << 1 | 1] += (r - mid) * tag[index];
            tag[index << 1] += tag[index];
            tag[index << 1 | 1] += tag[index]; 
            tag[index] = 0;
        }
        inline void update(int index)
        {
            cnt[index] = cnt[index << 1] + cnt[index << 1 | 1];
        }
        inline void modify(int now , int l , int r , int ql , int qr ,  int value)
        {
            if (l == ql && r == qr)
            {
                cnt[now] += 1ll * value * (qr - ql + 1);
                tag[now] += 1ll * value;
                return;
            }
            pushdown(now , l , r);
            int mid = (l + r) >> 1;
            if (mid >= qr) modify(now << 1 , l , mid , ql , qr , value);
            else if (mid + 1 <= ql) modify(now << 1 | 1 , mid + 1 , r , ql , qr , value);
            else
            {
                modify(now << 1 , l , mid , ql , mid , value);
                modify(now << 1 | 1 , mid + 1 , r , mid + 1 , qr , value);
            }
            update(now);
        }
        inline ll query(int now , int l , int r , int ql , int qr)
        {
            if (l == ql && r == qr)
                return cnt[now];
            pushdown(now , l , r);
            int mid = (l + r) >> 1;
            if (mid >= qr) return query(now << 1 , l , mid , ql , qr);
            else if (mid + 1 <= ql) return query(now << 1 | 1 , mid + 1 , r , ql , qr);
            else return query(now << 1 , l , mid , ql , mid) + query(now << 1 | 1 , mid + 1 , r , mid + 1 , qr);
        }
    } SGT;
    template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
    template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
    template <typename T> inline void read(T &x)
    {
       T f = 1; x = 0;
       char c = getchar();
       for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
       for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
       x *= f;
    }
    inline void divide(int l , int r , int L , int R)
    {
        static query tl[MAXN] , tr[MAXN];
        int mid = (l + r) >> 1;
        if (L > R) return;
        if (l == r)
        {
            for (int i = L; i <= R; i++)
                if (q[i].type == 2) ans[q[i].id] = mid;
            return;
        } else
        {
            int pl = 0 , pr = 0;
            for (int i = L; i <= R; i++) 
            {  
                if (q[i].type == 1) 
                { 
                    if (q[i].c > mid) 
                    {
                        tr[++pr] = q[i];
                        SGT.modify(1 , 1 , n , q[i].a , q[i].b , 1);
                    } else tl[++pl] = q[i];
                } else
                {
                    if (SGT.query(1 , 1 , n , q[i].a , q[i].b) >= q[i].c)
                        tr[++pr] = q[i];
                    else
                    {
                        q[i].c -= SGT.query(1 , 1 , n , q[i].a , q[i].b);
                        tl[++pl] = q[i];    
                    }    
                }
            }    
            for (int i = L; i <= R; i++)
                if (q[i].type == 1 && q[i].c > mid) SGT.modify(1 , 1 , n , q[i].a , q[i].b , -1);
            for (int i = L; i <= L + pl - 1; i++) q[i] = tl[i - L + 1];
            for (int i = L + pl; i <= R; i++) q[i] = tr[i - L - pl + 1];
            divide(l , mid , L , L + pl - 1);
            divide(mid + 1 , r , L + pl , R);
        }    
    }
    
    int main()
    {
        
        read(n); read(m);
        vector< int > que;
        for (int i = 1; i <= m; i++)
        {
            read(q[i].type);
            read(q[i].a);
            read(q[i].b);
            read(q[i].c);
            q[i].id = i;
            if (q[i].type == 2) que.push_back(i);
        }
        divide(-n , n , 1 , m);
        for (unsigned i = 0; i < que.size(); i++) printf("%d
    " , ans[que[i]]);
        
        return 0;
    }
  • 相关阅读:
    UITextField小结
    由iPhone项目生成iPad项目
    ios界面动画小结
    UIImagePickerController Class
    Xcode调试相关小结
    cocos2d简易引导
    python 多个装饰器组合应用,实现面向切面之AOP编程
    python 元类型编程, 单例模式SingleTon的一种实现方式
    python 实现简单的PerformanceCountCallHandler装饰器
    wxpython 之 GDI(二)
  • 原文地址:https://www.cnblogs.com/evenbao/p/10355687.html
Copyright © 2011-2022 走看看