NYOJ 600花儿朵朵

 1 //本题的关键是离散化,不然数组的空间不能开那么大,接下来运用树状数组来存储,查找,问题便可迎刃而解
 2 
 3 #include<iostream>
 4 #include<memory.h>
 5 #include<algorithm>
 6 #include<cstdio>
 7 using namespace std;
 8 #define M 300005
 9 
10 struct node{
11     int id,num; //id为记录输入的顺序,是建立一一映射的关键
12 }a[M];
13 
14 bool cmp(node a,node b){
15     return a.num < b.num;
16 }
17 
18 int s[M],Tree[M];
19 
20 int lowbit(int n){
21     return n&(-n);
22 }
23 
24 void update(int x,int d){
25     while(x>0){
26         Tree[x] += d;
27         x -= lowbit(x);
28     }
29 }
30 
31 void getsum(int x){
32     int sum = 0;
33     while(x<M){
34         sum += Tree[x];
35         x += lowbit(x);
36     }
37     printf("%d\n",sum);
38 }
39 
40 int main(){
41 //    freopen("in.txt","r",stdin);
42     int t,n,i,m,value;
43     scanf("%d",&t);
44     while(t--){
45         memset(Tree,0,sizeof(Tree));
46         memset(s,0,sizeof(s));
47         scanf("%d%d",&n,&m);
48         int sum = n*2+m; //把所有要输入的数据综合到一块,然后建立一一映射的关系(把大数变成小数,以缩小存储空间)
49         for(i=0; i<sum; ++i){
50             scanf("%d",&a[i].num);
51             a[i].id = i;
52         }
53         sort(a,a+sum,cmp); 
54         int count = 0;
55         s[ a[0].id ] = ++count;  
56         for(i=1; i<sum; ++i){       //大数变小,建立成映射关系
57             if(a[i].num != a[i-1].num)
58                 s[a[i].id] = ++count;
59             else
60                 s[a[i].id] = count;
61         }
62         for(i=0; i<n*2; i+=2){  //更新树状数组结点信息(插线取点法)
63             update(s[i+1],1);
64             update(s[i]-1,-1);
65         }
66         for(i=n*2; i<sum; ++i)
67             getsum(s[i]);
68     }
69     return 0;
70 }

 

posted @ 2013-04-06 00:54  YaLing  阅读(201)  评论(0编辑  收藏  举报