题意:给出3e5条线段,有3e5个询问,询问的内容给总共3e5个点,每次询问输出在询问点上的线段有多少个
分析:显然发现直接做不好做,因为存在重复的情况,还得考虑如何去重,这样得大概率确定到具体是哪个线,但这样想想也超了,极端的话3e5次询问,3e5个线都处理一遍,所以正难则反。发现每次询问只要处理出完全不被覆盖的,然后总数减去即可。
那么对于一次询问来说 —— 固定右端点,线段存左端点,直接从小到大枚举右端点,每次询问左端点到右端点的线段数(区间求和显然会想到BIT加速),最后 n - sum 就是当此询问的答案。
但是 —— 这个思路每次询问都要建一次BIT,(其实有个点二维偏序的意思 ),这样肯定不行,发现询问类似可以离线,所以离线降维。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+15;
const int mo = 998244353;
#define pb push_back
#define pii pair<int,int>
#define ft first
#define sd second
#define ffor(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define rfor(i,a,b,c) for(int i=(a);i>(b);i-=(c))
#define Rfor(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define all(x) (x).begin(), (x).end()
#define debug1(x) cerr<<"! "<<x<<endl;
#define debug2(x,y) cerr<<"# "<<x<<" "<<y<<endl;
class FenwickTree
{
public:
FenwickTree() {
c.resize(N);
}
int lowbit(int x) {
return x & (-x);
}
void upd(int pos, int x) {
while (pos < N) {
c[pos] += x;
pos += lowbit(pos);
}
}
int qry(int pos) {
int res = 0;
while (pos > 0) {
res += c[pos];
pos -= lowbit(pos);
}
return res;
}
int qry(int pa, int pb) {
if(pa > pb) return 0;
return qry(pb) - qry(pa - 1);
}
private:
vector<int> c;
};
void slv() {
vector<vector<int>> seg(N);
int n, m; cin >> n >> m;
For(i, 1, n, 1) {
int l, r; cin >> l >> r;
l++; r++;
seg[r].pb(l);
}
vector<int> ans(N);
vector<vector<int>> q(m + 1);
vector<vector<pii>> rq(N);
For(i, 0, m - 1, 1) {
int cnt; cin >> cnt;
// debug1(cnt)
q[i].pb(1);
For(j, 1, cnt, 1) {
int x; cin>>x; x++; q[i].pb(x);
}
q[i].pb(N - 1);
ffor(j, 0, q[i].size() - 1, 1) {
rq[q[i][j + 1] - 1].pb({q[i][j] + 1, i});
}
}
FenwickTree FT;
ffor(i, 1, N, 1) {
int sz = seg[i].size();
ffor(j, 0, sz, 1) {
FT.upd(seg[i][j], 1);
}
sz = rq[i].size();
ffor(j, 0, sz, 1) {
int idx = rq[i][j].sd;
int l = rq[i][j].ft;
ans[idx] += FT.qry(l, i);
// cout << idx << " " << l << " ";
// debug2(FT.qry(l, i), i)
}
}
For(i, 0, m - 1, 1) {
cout << n - ans[i] << '\n';
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
int t = 1; //cin>>t;
while(t--) {
slv();
}
}