码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI 2013] K大数查询

时间:2019-02-07 23:47:24      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:odi   tps   +=   max   ==   https   get   void   main   

[题目链接]

         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\n" , ans[que[i]]);
    
    return 0;
}

 

[ZJOI 2013] K大数查询

标签:odi   tps   +=   max   ==   https   get   void   main   

原文地址:https://www.cnblogs.com/evenbao/p/10355687.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!