Little Oregon loves to play in the forest, but tonight he got lost on his way back home. While trying to find his trail, he found a stream. No no, it was not a stream of hot water, rather it was a stream of 32 bit integers! Getting super excited, he sat by the stream and kept observing as the numbers kept coming. To his surprise, after coming out the numbers kept disappearing after a while! He asked Paka, the biggest tree by the stream, why the numbers were disappearing, and Paka replied that each number of the stream comes with an expiration time. Beyond its expiration point, that number gets eaten by the forest monster immediately. Each number has its own expiration time, and Paka offered that, as each number comes out, he will let Oregon know the expiration time of the number instantly. In exchange, sometimes Oregon will have to calculate the K’th smallest number of the numbers that has not expired yet, where K will be given by Paka. Oregon has recently signed up for ICPC Regional contest, so he thinks the deal Paka offered will be great for his practice. So let’s help Oregon with his regional al preparation. :) Input: Input starts with an integer T, then T cases follow. Each case starts with an integer, which represents the number of events E. Then E lines follow, each with one event. Each event is a list of integers separated by spaces.
A line of an event will be one of the following two types:
1. OP( = 1): CURRENT_TIMESTAMP VALUE END_TIMESTAMP This event starts with 1 which denotes the event type, followed by 3 integers: a. CURRENT_TIMESTAMP: the current timestamp b. VALUE: the value of the stream c. END_TIMESTAMP: the timestamp where this value will expire.
2. OP( = 2): CURRENT_TIMESTAMP K This event starts with 2 which denotes the event type, followed by 2 integers: a. CURRENT_TIMESTAMP: the current timestamp b. K: the position for the value that Paka is asking for. Explanation: Time is represented as a sequence of timestamps, which are 32 bit integers, the greater the timestamp implies the later the time. CURRENT_TIMESTAMP is the timestamp of a number coming out of the stream, or the timestamp of a query given by Paka. In the given inputs, the CURRENT_TIMESTAMPS will be strictly increasing between consecutive events.
And a number cannot expire before coming out of the stream, hence END_TIMESTAMP >= CURRENT_TIMESTAMP.
Constraints: 1. 1 = t. If no such number exists, then print -1.
题意:给予这样的两种操作,(一)、开始时间、价值、结束时间;(二)、查询目前时间点的第K小的价值,如果没有K个的话,就输出-1。
思路:我们用vector<>存每个离散时间戳上的加进去的值,还有要减去的值,然后因为题目中说的那样,查询时间是按照生序排列的,所以我们只需要去不断的进行对应的查询即可。查询第K大,用的是主席树的操作。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2e5 + 7;
int E, lsan[maxN], cnt, lv[maxN], num, len_t, _UP, in, ou, root = 1;
struct qtion
{
int L, R, val;
qtion(int b=0, int c=0, int d=0):L(b), R(c), val(d) {}
}ques[maxN];
struct need
{
int ti, k;
need(int a=0, int b=0):ti(a), k(b) {}
}nd[maxN];
int tree[30 * maxN], lc[30 * maxN], rc[30 * maxN], tot;
inline void update(int &rt, int l, int r, int pos, int val)
{
if(!rt)
{
rt = ++tot;
tree[rt] = 0;
lc[rt] = rc[rt] = 0;
}
tree[rt] += val;
if(l == r) return;
int mid = HalF;
if(pos <= mid) update(lc[rt], l, mid, pos, val);
else update(rc[rt], mid + 1, r, pos, val);
}
int query(int rt, int l, int r, int k)
{
if(l == r) return l;
int mid = HalF;
if(tree[lc[rt]] >= k) return query(lc[rt], l, mid, k);
else return query(rc[rt], mid + 1, r, k - tree[lc[rt]]);
}
vector<int> add[maxN], del[maxN];
inline void init()
{
cnt = num = in = ou = 0;
root = 1;
tot = 1;
tree[0] = lc[0] = rc[0] = 0;
tree[1] = lc[1] = rc[1] = 0;
}
int main()
{
int T; scanf("%d", &T);
for(int Cas=1; Cas<=T; Cas++)
{
scanf("%d", &E);
init();
for(int i=1, op; i<=E; i++)
{
scanf("%d", &op);
if(op == 1)
{
++in;
scanf("%d%d%d", &ques[in].L, &ques[in].val, &ques[in].R);
lsan[++cnt] = ques[in].L;
lsan[++cnt] = ques[in].R;
lv[++num] = ques[in].val;
}
else
{
++ou;
scanf("%d%d", &nd[ou].ti, &nd[ou].k);
lsan[++cnt] = nd[ou].ti;
}
}
sort(lsan + 1, lsan + cnt + 1);
sort(lv + 1, lv + num + 1);
len_t = (int)(unique(lsan + 1, lsan + cnt + 1) - lsan - 1);
_UP = (int)(unique(lv + 1, lv + num + 1) - lv - 1);
for(int i=1; i<=len_t; i++) { add[i].clear(); del[i].clear(); }
for(int i=1; i<=in; i++)
{
ques[i].L = (int)(lower_bound(lsan + 1, lsan + len_t + 1, ques[i].L) - lsan);
ques[i].R = (int)(lower_bound(lsan + 1, lsan + len_t + 1, ques[i].R) - lsan);
ques[i].val = (int)(lower_bound(lv + 1, lv + _UP + 1, ques[i].val) - lv);
add[ques[i].L].push_back(ques[i].val);
del[ques[i].R].push_back(ques[i].val);
}
for(int i=1; i<=ou; i++) nd[i].ti = (int)(lower_bound(lsan + 1, lsan + len_t + 1, nd[i].ti) - lsan);
int ti = 1;
printf("Case %d:\n", Cas);
for(int i=1; i<=ou; i++)
{
for(int j=ti, have; j<=nd[i].ti; j++)
{
have = (int)add[j].size();
for(int k=0; k<have; k++)
{
update(root, 1, _UP, add[j][k], 1);
}
}
for(int j=ti, have; j<nd[i].ti; j++)
{
have = (int)del[j].size();
for(int k=0; k<have; k++)
{
update(root, 1, _UP, del[j][k], -1);
}
}
if(tree[1] >= nd[i].k) printf("%d\n", lv[query(root, 1, _UP, nd[i].k)]);
else printf("-1\n");
int have = (int)del[nd[i].ti].size();
for(int k=0; k<have; k++)
{
update(root, 1, _UP, del[nd[i].ti][k], -1);
}
ti = nd[i].ti + 1;
}
}
return 0;
}