题解:P14394 [JOISC 2016] 俄罗斯套娃 / Matryoshka
把每一个套娃变成坐标系内的点
询问离线下来。离散化之后将询问按照
可以用前缀最大值树状数组维护。每次查询就是查询
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
int n, q, m, ans[N];
pair<int, int> pt[N];
map<int, int> mp;
struct query {
int x, y, pos;
}q1[N];
struct BIT {
int c[N << 2] = {0};
void add(int x, int k) {
for(; x <= m; x += x & -x) c[x] = max(c[x], k);
}
int ask(int x) {
int mx = 0;
for(; x; x -= x & -x) mx = max(mx, c[x]);
return mx;
}
}tr;
signed main() {
ios :: sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> q;
for(int i = 1; i <= n; i ++) {
cin >> pt[i].first >> pt[i].second;
mp[pt[i].first] = 1, mp[pt[i].second] = 1;
}
sort(pt + 1, pt + 1 + n, [](pair<int, int> pa, pair<int, int> pb) {
if(pa.first != pb.first) return pa.first > pb.first;
return pa.second < pb.second;
});
for(int i = 1; i <= q; i ++) {
cin >> q1[i].x >> q1[i].y;
mp[q1[i].x] = 1, mp[q1[i].y] = 1;
q1[i].pos = i;
}
sort(q1 + 1, q1 + 1 + q, [](query qa, query qb) {
return qa.x > qb.x;
});
for(auto &tmp : mp) tmp.second = ++ m;
int t = 1;
for(int i = 1; i <= n; i ++)
pt[i].first = mp[pt[i].first], pt[i].second = mp[pt[i].second];
for(int i = 1; i <= q; i ++) {
q1[i].x = mp[q1[i].x], q1[i].y = mp[q1[i].y];
while(t <= n && pt[t].first >= q1[i].x)
tr.add(pt[t].second, tr.ask(pt[t].second) + 1), t ++;
ans[q1[i].pos] = tr.ask(q1[i].y);
}
for(int i = 1; i <= q; i ++) cout << ans[i] << '\n';
return 0;
}