The Stream of Corning 2 --- Gym - 102091K(区间第 k 大--权值线段树)

题目

  https://vjudge.net/problem/Gym-102091K

题意

  给出 T 组数据,每组数据给出 n 个操作,操作分为下列两种:

  操作 1:在 L 到 R 这个时间段内加入 W。(输入顺序:op,L,K,W)

  操作 2:问 T 这个时间点第 K 大的数是什么。(输入顺序:op,T,K)

  tip:题目保证时间段 L 和 时间点 T 按照增序输入。

题解

  因为时间一定按照增序输入,那么只需要用优先队列记录时间段,将 R 小于 T 的时间段都退出,维护权值线段树即可。即可个鬼啊,输入数据 T 到死……

  小提示:加一个神仙快读,可以直接少3倍时间(wdnmd)

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define ull unsigned long long
 4 #define met(a, b) memset(a, b, sizeof(a))
 5 #define rep(i, a, b) for(int i = a; i <= b; i++)
 6 #define bep(i, a, b) for(int i = a; i >= b; i--)
 7 #define lowbit(x) (x&(-x))
 8 #define MID ((l + r) / 2)
 9 #define ls (pos<<1)
10 #define rs ((pos<<1)+1)
11 #define pb push_back
12 #define ios() ios::sync_with_stdio(0)
13 
14 using namespace std;
15 
16 const int maxn = 1e5 + 1010;
17 const int inf = 0x3f3f3f3f;
18 const ll INF = 0x3f3f3f3f3f3f3f3f;
19 const ll mod = 123456789;
20 const double eps = 1e-4;
21 
22 struct NODE {
23     int op, l, w, r;
24 }arr[maxn];
25 struct node {
26     int l, r, w;
27     bool operator < (const node &a) const {
28         return a.r < r;
29     }
30 };
31 
32 int root[maxn*12];
33 int b[maxn], tail;
34 priority_queue<node> que;
35 
36 void update(int pos, int l, int r, int k, int val) {
37     if(l == r) {
38         root[pos] += val;
39         return;
40     }
41     if(k <= MID) update(ls, l, MID, k, val);
42     else update(rs, MID + 1, r, k, val);
43     root[pos] = root[ls] + root[rs];
44 }
45 int query(int pos, int l, int r, int k) {
46     if(k > root[pos]) return -1;
47     if(l == r) return l;
48     if(root[ls] >= k) return query(ls, l, MID, k);
49     else return query(rs, MID + 1, r, k - root[ls]);
50 }
51 
52 int main() {
53     int T, k = 0;
54     scanf("%d", &T);
55     while(T--) {
56         tail = 0;
57         int n;
58         scanf("%d", &n);
59         rep(i, 1, n) {
60             scanf("%d", &arr[i].op);
61             if(arr[i].op == 1) scanf("%d%d%d", &arr[i].l, &arr[i].w, &arr[i].r);
62             else scanf("%d%d", &arr[i].l, &arr[i].r);
63             if(arr[i].op == 1) b[++tail] = arr[i].w;
64         }
65         sort(b + 1, b + 1 + tail);
66         tail = unique(b + 1, b + 1 + tail) - b - 1;
67         printf("Case %d:\n", ++k);
68         rep(i, 1, n) {
69             if(arr[i].op == 1) {
70                 int pos = lower_bound(b + 1, b + 1 + tail, arr[i].w) - b;
71                 que.push((node){arr[i].l, arr[i].r, arr[i].w});
72                 update(1, 1, tail, pos, 1);
73             }
74             else {
75                 while(!que.empty()) {
76                     node t = que.top();
77                     if(t.r >= arr[i].l) break;
78                     que.pop();
79                     int pos = lower_bound(b + 1, b + 1 + tail, t.w) - b;
80                     update(1, 1, tail, pos, -1);
81                 }
82                 int pos = query(1, 1, tail, arr[i].r);
83                 if(pos == -1) printf("-1\n");
84                 else printf("%d\n", b[pos]);
85             }
86         }
87         while(!que.empty()) {
88             node t = que.top();
89             que.pop();
90             int pos = lower_bound(b + 1, b + 1 + tail, t.w) - b;
91             update(1, 1, tail, pos, -1);
92         }
93     }
94     return 0;
95 }
posted @ 2020-01-13 21:14  Ruby·Z  阅读(152)  评论(0编辑  收藏  举报