描述 Description
有N条线段,已知每条线段的起点和终点(50000以内),然后有M个询问,每次询问一个点(50000以内),求这个点在多少条线段上出现过?
输入格式 InputFormat
第一行N线段条数
接下来N行,每行两个数,线段的起点和终点
第N+2行一个数M询问个数
接下来M行,每行一个点
接下来N行,每行两个数,线段的起点和终点
第N+2行一个数M询问个数
接下来M行,每行一个点
输出格式 OutputFormat
对于每个询问,求答案
样例输入 SampleInput
[复制数据]
3
2 5
4 6
0 7
4
2
4
7
6
2 5
4 6
0 7
4
2
4
7
6
样例输出 SampleOutput [复制数据]
2
3
1
2
代码:
/* 这个题目如果直接模拟 50000*50000的计算量,肯定超时; 技巧: 询问第n个数在几个线段之内,我们可以发现,n之前的起始点的数目减去终点的数目即等于在几个线段内的数目。 考虑开两个数组,一个存放线段起始点,一个存放线段终点。 最后在经过一个预处理,计算从1-n的起始点数目或者终点数目,并存入数组a[n]与b[n]中。 结果即为: a[n]-b[n-1]; 但是要注意起点和终点可能有负! 多开一倍的数组来处理; */ #include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define N 101000 int a[N],b[N]; int main() { int i,j,n,m,x,y; while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a));memset(b,0,sizeof(b)); for(i=0;i<n;i++) { scanf("%d %d",&x,&y); if(x>=0) a[x+50000]++; else { x=50000+x; a[x]++; } if(y>=0) b[y+50000]++; else { y=y+50000; b[y++]; } } //预处理起始数组与终止数组。 for(i=1;i<N;i++) { a[i]=a[i-1]+a[i]; b[i]=b[i-1]+b[i]; } scanf("%d",&m); while(m--) { scanf("%d",&x); x=x+50000; if(x==0) printf("%d\n",a[0]); else printf("%d\n",a[x]-b[x-1]); } } return 0; }