题意:
给你n个区间,然后给你m个i点问你这个点在几个所给定的区间里;
思路:
给你n个区间,然后给你m个i点问你这个点在几个所给定的区间里;
思路:
离散化+区间覆盖
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e4+10;
struct SegT{
int left,right;
int val;
int flag;
};
SegT q[N*12];
int n,Q;
int arr[N*4];
void Build(int num,int L,int R)
{
q[num].left=L;
q[num].right=R;
q[num].flag=q[num].val=0;
if(L==R)
return;
int mid=(L+R)/2;
Build(2*num, L,mid);
Build(2*num+1,mid+1,R);
}
void Pushdown(int num)
{
if(q[num].flag)
{
q[2*num].val+=(q[2*num].right-q[2*num].left+1)*q[num].flag;
q[2*num+1].val+=(q[2*num+1].right-q[2*num+1].left+1)*q[num].flag;
q[2*num].flag+=q[num].flag;
q[2*num+1].flag+=q[num].flag;
q[num].flag=0;
}
}
void Update(int num,int s,int t)
{
if(q[num].left>=s&&q[num].right<=t)
{
q[num].flag+=1;
q[num].val+=(q[num].right-q[num].left+1); //wa在了这里。。只要加1就行了,无奈给乘了。。。q[num].flag...不过还是有长进///
return;
}
Pushdown(num);
int mid=(q[num].left+q[num].right)/2;
if(mid>=t)
Update(2*num,s,t);
else if(mid<s)
Update(2*num+1,s,t);
else
{
Update(2*num,s,mid);
Update(2*num+1,mid+1,t);
}
q[num].val=q[2*num].val+q[2*num+1].val;
}
int query(int num,int id)
{
if(q[num].left==id&&q[num].left==q[num].right)
return q[num].val;
Pushdown(num);
int mid=(q[num].right+q[num].left)/2;
if(mid>=id)
return query(2*num,id);
else
return query(2*num+1,id);
}
vector<int>xs;
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&Q);
xs.clear();
for(int i=1;i<=2*n;i+=2)
{
scanf("%d%d",&arr[i],&arr[i+1]);
xs.push_back(arr[i]);
xs.push_back(arr[i+1]);
}
for(int i=1;i<=Q;i++)
{
scanf("%d",&arr[i+2*n]);
xs.push_back(arr[i+2*n]);
}
int num=0;
sort(xs.begin(),xs.end());
vector<int>::iterator e=unique(xs.begin(),xs.end());
for(int i=1;i<=2*n+Q;i++)
{
arr[i]=lower_bound(xs.begin(),e,arr[i])-xs.begin()+1;
num=max(num,arr[i]);
}
Build(1,1,num);
for(int i=1;i<=2*n;i+=2)
Update(1,arr[i],arr[i+1]);
printf("Case %d:\n",cas++);
for(int i=1;i<=Q;i++)
printf("%d\n",query(1,arr[i+2*n]));
}
return 0;
}
/*
5 4
6 12
8 8
10 12
8 11
0 12
11
12
2
20
3 3
1 3
2 4
5 6
1
2
3
*/