记录编号 357278 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2013] K大数查询 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 2.430 s
提交时间 2016-12-10 10:13:09 内存使用 6.30 MiB
显示代码纯文本
//%cstdio
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <list>
#include <queue>
#include <vector>
#include <cstdarg>
using namespace std;
namespace IO
{
char buf[1<<18], *fs, *ft;
inline char readc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<18,stdin),fs==ft))?0:*fs++;
}
inline int fast_read()
{
    int r;
    char c;
    bool s = false;
    while(c = readc())
    {
        if(c >= '0' && c <= '9')
        {
            r = c^0x30;
            break;
        }else if(c == '-')s = true;
    }
    while(isdigit(c = readc()))
        r = (r<<3)+(r<<1)+(c^0x30);
    return s?-r:r;
}

}using IO::fast_read;

namespace segtree
{

struct node
{
    int l; int r;
    int ls, rs;
    int sum;
    int lazy;
    void addv(int v)
    {
        lazy += v;
        sum += (r-l+1)*v;
    }
}ns[110001];
int last = 1;
#define ld ns[d.ls]
#define rd ns[d.rs]
inline void pushup(node &d)
{
    d.sum = ld.sum + rd.sum;
}
int build(int l, int r)
{
    if(l > r)return 0;
    int c = last++;
    node &d = ns[c];
    d.l = l;
    d.r = r;
    if(l < r)
    {
        int m = (l+r)>>1;
        d.ls = build(l, m);
        d.rs = build(m+1, r);
    }
    return c;
}
inline void pushdown(node &d)
{
    if(d.lazy)
    {
        ld.addv(d.lazy);
        rd.addv(d.lazy);
        d.lazy = 0;
    }
}
int query(int c, int l, int r)
{
    if(!c)return 0;
    node &d = ns[c];
    if(d.l == l && r == d.r)return d.sum;
    else{
        pushdown(d);
        if(l >= rd.l)return query(d.rs, l, r);
        else if(r <= ld.r)return query(d.ls, l, r);
        else return query(d.ls, l, ld.r)+query(d.rs, rd.l, r);
    }
}
void addval(int c, int l, int r, int v)
{
    if(!c)return;
    node &d = ns[c];
    if(d.l == l && r == d.r)d.addv(v);
    else{
        pushdown(d);
        if(l >= rd.l)addval(d.rs, l, r, v);
        else if(r <= ld.r)addval(d.ls, l, r, v);
        else{
            addval(d.ls, l, ld.r, v);
            addval(d.rs, rd.l, r, v);
        }
        pushup(d);
    }
}

}using segtree::query; using segtree::addval;
int N, M;
int ques = 0;
int mn = 0x7fffffff, mx = 0;
struct que
{
    int id, cmd, a, b, c;
}qs[50050], s1[50050], s2[50050];
int ans[50050];
int cnt[50050];
void solve(int a, int b, int l, int r)  //操作qs[a, b] 的答案均在 [l, r]内
{
    if(l == r)
    {
        for(int i = a; i <= b; i++)if(qs[i].cmd == 2)ans[qs[i].id] = l;
        return;
    }
    int m = (long long)(l+r)>>1;
    for(int i = a; i <= b; i++)
    {
        if(qs[i].cmd == 1)
        {
            if(qs[i].c >= m+1)addval(1, qs[i].a, qs[i].b, 1);
        }else if(qs[i].cmd == 2)
            cnt[i] = query(1, qs[i].a, qs[i].b);
    }
    for(int i = a; i <= b; i++) //撤销
        if(qs[i].cmd == 1 && qs[i].c >= m+1)addval(1, qs[i].a, qs[i].b, -1);
    int p1 = 0, p2 = 0;
    for(int i = a; i <= b; i++)
    {
        if(qs[i].cmd == 1)
        {
            if(qs[i].c <= m)s1[p1++] = qs[i];else s2[p2++] = qs[i];
        }else if(qs[i].cmd == 2)
        {
            if(cnt[i] >= qs[i].c)s2[p2++] = qs[i];
            else qs[i].c -= cnt[i], s1[p1++] = qs[i];
        }
    }
    for(int i = 0; i < p1; i++)qs[a+i] = s1[i];
    for(int i = 0; i < p2; i++)qs[a+p1+i] = s2[i];
    solve(a, a+p1-1, l, m);
    solve(a+p1, b, m+1, r);
}
int main()
{
    //freopen("test_data.txt", "r", stdin);
    freopen("zjoi13_sequence.in", "r", stdin);
    freopen("zjoi13_sequence.out", "w", stdout);
    N = fast_read();
    M = fast_read();
    segtree::build(0, N);
    for(int i = 1; i <= M; i++)
    {
        qs[i].cmd = fast_read();
        qs[i].a = fast_read();
        qs[i].b = fast_read();
        qs[i].c = fast_read();
        if(qs[i].cmd == 2)qs[i].id = ++ques;
        else mn = min(mn, qs[i].c), mx = max(mx, qs[i].c);
    }
    solve(1, M, mn, mx);
    for(int i = 1; i <= ques; i++)
        printf("%d\n", ans[i]);
    return 0;
}