先摆官方题解吧.........
....................有什么好讲的呢.......
注意一些地方常数优化一下.......然后......$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(' '); } #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; }