习题:Valera and Queries(树状数组)
题目
思路
正难则反
考虑有哪些节点没有被任何一条线段所覆盖
离线之后用一种类似于扫描线的做法即可
代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
namespace BIT
{
int N=1000015;
int b[1000015];
int lowbit(int x)
{
return x&(-x);
}
void update(int k,int val)
{
for(int i=k;i<N;i+=lowbit(i))
b[i]+=val;
}
int ask(int k)
{
int ret=0;
for(int i=k;i;i-=lowbit(i))
ret+=b[i];
return ret;
}
}
using namespace BIT;
struct node
{
int l,r,id;
friend bool operator < (const node &a,const node &b)
{
if(a.l!=b.l)
return a.l>b.l;
if(a.r!=b.r)
return a.r<b.r;
return a.id<b.id;
}
};
int len;
int n,m;
int ans[300005];
vector<node> a;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int l,r;
cin>>l>>r;
a.push_back((node){l,r,0});
}
len=n+1;
for(int i=1,cnt,la;i<=m;i++)
{
cin>>cnt;
ans[i]=n;
la=0;
for(int j=1,p;j<=cnt;j++)
{
cin>>p;
a.push_back((node){la+1,p-1,i});
la=p;
}
a.push_back((node){la+1,1000005,i});
}
sort(a.begin(),a.end());
for(int i=0;i<a.size();i++)
{
if(a[i].id)
ans[a[i].id]-=ask(a[i].r);
else
update(a[i].r,1);
}
for(int i=1;i<=m;i++)
cout<<ans[i]<<'\n';
return 0;
}

浙公网安备 33010602011771号