Interval Noj

Interval
时间限制:2000 ms  |  内存限制:65535 KB 
描述 
There are n(1 <= n <= 100000) intervals [ai, bi] and m(1 <= m <= 100000) queries, -100000 <= ai <= bi <= 100000 are integers.
Each query contains an integer xi(-100000 <= x <= 100000). For each query, you should answer how many intervals convers xi.
输入 
The first line of input is the number of test case.
For each test case,
two integers n m on the first line, 
then n lines, each line contains two integers ai, bi;
then m lines, each line contains an integer xi. 
输出 
m lines, each line an integer, the number of intervals that covers xi. 
样例输入 
2
3 4
1 3
1 2
2 3
0
1
2
3
1 3
0 0
-1
0
1样例输出 
0
2
3
2
0
1
0

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 100010
int Z[N],F[N];

int lowbit(int n){
	return n&(-n);
}

void update(int x,int n,int value){
	while(n>0){
		if(x>0)
			Z[n]+=value;
		else
			F[n]+=value;
		n-=lowbit(n);
	}
}

int getsum(int x,int n){
	int s=0;
	while(n<N){
		if(x>0)
			s+=Z[n];
		else
			s+=F[n];
		n+=lowbit(n);
	}
	return s;
}

int main()
{
	//freopen("in.txt","r",stdin);
	int t,n,m,a,b,c,i;
	scanf("%d",&t);
	while(t--){
		memset(Z,0,sizeof(Z));
		memset(F,0,sizeof(F));
		scanf("%d%d",&n,&m);
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&a,&b);
			if(a==0 && b==0){F[0]+=1;}
			else if(a==0 && b!=0){	F[0]+=1;a+=1;}
			else if(a!=0 && b==0)	{	F[0]+=1;b+=1;}
			if(a>0){
				update(1,b,1);
				update(1,a-1,-1);
			}
			else if(a<0 && b>0){
				F[0]+=1;
				update(0,-a,1);
				update(1,b,1);
			}
			else if(a<0 && b<0){
				update(0,-a,1);
				update(0,(-b-1),-1);
			}
		}
		for(i=0; i<m; i++){
			int s=0;
			scanf("%d",&c);
			if(c>0)
				s=getsum(1,c);
			else if(c<0)
				s=getsum(0,-c);
			else
				s=F[0];
			printf("%d\n",s);
		}
	}
	return 0;
}

//采取的思路与士兵杀敌四一样,不同的是,还要给区间为负数的定义一个数组来存放,代码有点长,但很简单!

原文地址:https://www.cnblogs.com/yaling/p/2969950.html