(2012-07-27 23:32:00)
SOJ4122:http://cstest.scu.edu.cn/soj/problem.action?id=4122
赤裸裸的一道题线段树题,也是最简单的一种情况。自己手敲了一个线段树。
#include<iostream>
using namespace std;
//#define N 10
struct node
{
int L;//左端点。
int R;//右端点。
int count;//个数。
node *left;
node *right;
node(int a,int b)//构造函数。
{
L=a;
R=b;
left=NULL;
right=NULL;
count=0;
}
};
void con_tree(node *root)//建立线段树。
{
if(root->L==root->R)
return ;
int mid=(root->L+root->R)/2;
if(root->L<0 && root->R==root->L+1)//////////////////////
mid=root->L;
root->left=new node(root->L,mid);
con_tree(root->left);
root->right=new node(mid+1,root->R);
con_tree(root->right);
}
void clear(node *root)//清零。
{
if(root)
{
root->count=0;
clear(root->left);
clear(root->right);
}
}
void insert(node *root,int a,int b)//插入线段。
{
int mid=(root->L+root->R)/2;
if(root->L<0 && root->R==root->L+1)/////////////////////
mid=root->L;
if(a==root->L && b==root->R)
{
root->count++;
return ;
}
else if(b<=mid)
{
insert(root->left,a,b);
}
else if(a>mid)
{
insert(root->right,a,b);
}
else
{
insert(root->left,a,mid);
insert(root->right,mid+1,b);
}
}
int search(node *root,int target)//搜索。
{
int sum=0;
int mid;
while(root)
{
sum+=root->count;
mid=(root->L+root->R)/2;
if(root->L<0 && root->R==root->L+1)////////////////////////
mid=root->L;
if(target<=mid)
root=root->left;
else
root=root->right;
}
return sum;
}
void del(node *root)//删除线段树。
{
if(root->left)
del(root->left);
if(root->right)
del(root->right);
delete root;
}
int main()
{
int n,m;
int i;
node *root=new node(-100000,100000);
con_tree(root);
int a,b,c;
int test;
scanf("%d",&test);
while(test--)//n is the number of lines and m is the number of inquiries.
{
clear(root);
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
insert(root,a,b);
}
for(i=0;i<m;i++)
{
scanf("%d",&c);
printf("%d\n",search(root,c));
}
}
// del(root);
return 0;
}