分析:很经典的区间覆盖问题,给
n
个线段,问
如果要完全覆盖,那么 l>=L,r<=R ,如果这个时候我们把区间加入线段的序列,按照右端点 r <script type="math/tex" id="MathJax-Element-476">r</script>来排序,用一颗线段树来维护所有的左端点,那么就是一个线段树的插入+查询操作。
此题离线做就可以了。
代码:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define sc(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define lrt rt<<1
#define rrt rt<<1|1
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid,r
typedef long long LL;
typedef vector <int> VI;
typedef pair <int,int> PII;
const int inf = 1000010;
const int maxn = 300030;
int n,m;
struct Node{
int l,r;
int id;
Node() {}
Node(int x,int y,int z) : l(x),r(y),id(z) {}
bool operator < (const Node& rhs) const{
if(r == rhs.r) return id > rhs.id;
return r < rhs.r;
}
}node[maxn<<1];
int c[inf];
int lowbit(int x) {return x&-x;}
void modify(int x,int val){
for(;x < inf;x += lowbit(x)) c[x] += val;
}
int query(int x){
int ans = 0;
for(;x;x -= lowbit(x)) ans += c[x];
return ans;
}
int ans[maxn];
int main(){
//freopen("in.txt","r",stdin);
while(~sc2(n,m)){
FOR(i,0,inf) c[i] = 0;
int cnt = 0;
FOR(i,0,n){
int l,r; sc2(l,r);
node[cnt++] = Node(l,r,0);
}
FOR(i,1,m+1){
int k,r; sc(k);
int last = 0;
FOR(j,0,k){
sc(r); node[cnt++] = Node(last,r,i);
last = r;
}
node[cnt++] = Node(last,inf-1,i);
}
sort(node,node+cnt);
memset(ans,0,sizeof(ans));
FOR(i,0,cnt){
//printf("%d %d %d\n",node[i].l,node[i].r,node[i].id);
if(!node[i].id){
modify(node[i].l,1);
}
else{
ans[node[i].id] += query(inf-1)-query(node[i].l);
//printf("ans : %d %d ",query(inf-1),query(node[i].l));
//printf("%d\n",ans[node[i].id]);
}
}
FOR(i,1,m+1){
printf("%d\n",n-ans[i]);
}
}
return 0;
}