题目链接
把时间排序后离散化再操作(又是手动去重手动二分查找)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int sum[N*2];
int q[N];//询问
int n,m;
int maxn;//实际时间上限
int st[N],ed[N];//起点终点
int time[N*4];//时间线
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int val)
{
while(x<=maxn)
{
sum[x]+=val;
x+=lowbit(x);
}
}
void range_add(int l,int r,int val)
{
add(l,val);add(r+1,-val);
}
int query(int x)
{
int ret=0;
while(x)
{
ret+=sum[x];
x-=lowbit(x);
}
return ret;
}
int bs(int t,int r)//二分查找
{
r--;
int l=0,mid;
while(l<=r)
{
mid=l+r>>1;
if(time[mid]==t)return mid;
if(time[mid]<t)l=mid+1;
else r=mid-1;
}
}
int main()
{
//freopen("in.txt","r",stdin);
int k,i,top;
scanf("%d",&k);
for(int ca=1;ca<=k;ca++)
{
top=0;
memset(sum,0,sizeof(sum));
memset(time,0,sizeof(time));
printf("Case #%d:\n",ca);
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d%d",&st[i],&ed[i]);
time[top++]=st[i];
time[top++]=ed[i];
}
for(i=0;i<m;i++)
{
scanf("%d",&q[i]);
time[top++]=q[i];
}
sort(time,time+top);
int t=1;
for(int i=1;i<top;i++)
if(time[i]!=time[i-1])time[t++]=time[i];//去重
maxn=t+1;
sort(time,time+t);
for(int i=0;i<n;i++)
{
int l=bs(st[i],t);
int r=bs(ed[i],t);
range_add(l+1,r+1,1);
}
for(int i=0;i<m;i++)
{
int ask=bs(q[i],t);
printf("%d\n",query(ask+1));
}
}
return 0;
}