51nod1981 如何愉快地与STL玩耍

先摆官方题解吧.........

....................有什么好讲的呢.......

注意一些地方常数优化一下.......然后......$bitset$怎么暴力怎么来吧......

仿佛有神仙$n \log^3 n$跑过了......只能$orz$....

#include <cstdio>
#include <bitset>
#include <cstring>
#include <iostream>
using namespace std;

extern inline char gc() {
    static char RR[23456], *S = RR + 23333, *T = RR + 23333;
    if(S == T) fread(RR, 1, 23333, stdin), S = RR;
    return *S ++;
}
inline int read() {
    int p = 0, w = 1; char c = gc();
    while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
    while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
    return p * w;
}

int wr[50], rw;
#define pc(o) *O ++ = o
char WR[50000005], *O = WR;
inline void write(int x) {
    if(!x) pc('0');
    if(x < 0) x = -x, pc('-');
    while(x) wr[++ rw] = x % 10, x /= 10;
    while(rw) pc(wr[rw --] + '0'); pc('\n');
}

#define ri register int
#define sid 65555
#define wid 10005

int n, q, rt, id;
struct seg {
    int ls, rs;
    bitset <wid> v, tag; 
} t[sid * 2];
bitset <wid> ask, sum[wid];

void ins(int &o, int l, int r, int ml, int mr, int c) {
    if(ml > r || mr < l) return;
    if(!o) o = ++ id; t[o].v[c] = 1;
    if(ml <= l && mr >= r) { t[o].tag[c] = 1; return; }
    int mid = (l + r) >> 1;
    ins(t[o].ls, l, mid, ml, mr, c);
    ins(t[o].rs, mid + 1, r, ml, mr, c);
}

void qry(int &o, int l, int r, int ml, int mr) {
    if(ml > r || mr < l || !o) return;
    if(ml <= l && mr >= r) { ask |= t[o].v; return; }
    ask |= t[o].tag;
    int mid = (l + r) >> 1;
    qry(t[o].ls, l, mid, ml, mr);
    qry(t[o].rs, mid + 1, r, ml, mr);
}

int qry(int l, int r, int k) {
    ask.reset();
    qry(rt, 1, n, l, r);
    if(ask.count() < k || k == 0) return -1;
    int L = 0, R = 10000, ans = -1;
    while(L <= R) {
        int mid = (L + R) >> 1;
        if((ask & sum[mid]).count() >= k) R = mid - 1, ans = mid;
        else L = mid + 1;
    }
    return ans;
}

int main() {
    
    sum[0][0] = 1;
    for(ri i = 1; i <= 10000; i ++) {
        sum[i] = sum[i - 1];
        sum[i][i] = 1;
    }

    n = read(); q = read();
    for(ri i = 1; i <= q; i ++) {
        int opt = read(), L = read(), R = read();
        if(opt == 1) ins(rt, 1, n, L, R, read());
        else write(qry(L, R, read()));
    }
    fwrite(WR, 1, O - WR, stdout);
    return 0;
}

 

posted @ 2018-08-23 16:32  remoon  阅读(260)  评论(0编辑  收藏  举报