主席树 hdu 4417

求一个区间内小于等于limit的数;

主席树模板题。

求出每一个节点的sum;

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<math.h>
 4 #include<string.h>
 5 using namespace std;
 6 const int maxn=1e5+10;
 7 int a[maxn],b[maxn*2],cnt,len;
 8 struct Node{int l,r,limit;}ask[maxn];
 9 int Root[maxn];
10 struct node{int ln,rn,sum;}tree[maxn*40];
11 void build(int &x,int l,int r)
12 {
13     ++cnt;
14     x=cnt;
15     tree[cnt].sum=0;
16     if(l==r) return;
17     int mid=l+r>>1;
18     build(tree[cnt].ln,l,mid);
19     build(tree[cnt].rn,mid+1,r);
20 }
21 void add(int pos,int l,int r,int &x,int y)
22 {
23     tree[++cnt]=tree[y];
24     tree[cnt].sum++;
25     x=cnt;
26     int mid=l+r>>1;
27     if(l==r) return;
28     if(pos<=mid) add(pos,l,mid,tree[cnt].ln,tree[y].ln);
29     else       add(pos,mid+1,r,tree[cnt].rn,tree[y].rn);
30     return;
31 }
32 int query(int l,int r,int x,int y,int limit)
33 {
34     int mid=l+r>>1;
35     int ans=0;
36     if(l==r){
37         int tmp=tree[y].sum-tree[x].sum;
38         return tmp;
39     }
40     if(limit>mid){
41         int left1=tree[x].ln,left2=tree[y].ln;
42         ans+=tree[left2].sum-tree[left1].sum;
43         if(limit>mid) ans+=query(mid+1,r,tree[x].rn,tree[y].rn,limit);
44     }
45     else{
46         ans+=query(l,mid,tree[x].ln,tree[y].ln,limit);
47     }
48     return ans;
49 }
50 void init()
51 {
52     cnt=0;
53 }
54 int main()
55 {
56     int T;
57     scanf("%d",&T);
58     int ccnt=0;
59     while(T--){
60         init();
61         int n,m;
62         scanf("%d%d",&n,&m);
63         for(int i=1;i<=n;i++){
64             scanf("%d",&a[i]);
65             b[++cnt]=a[i];
66         }
67         for(int i=1;i<=m;i++){
68             scanf("%d%d%d",&ask[i].l,&ask[i].r,&ask[i].limit);
69             ask[i].l++;ask[i].r++;
70             b[++cnt]=ask[i].limit;
71         }
72         sort(b+1,b+1+cnt);
73         len=unique(b+1,b+1+cnt)-b-1;
74         build(Root[0],1,len);
75         for(int i=1;i<=n;i++){
76             a[i]=lower_bound(b+1,b+1+len,a[i])-b;
77             add(a[i],1,len,Root[i],Root[i-1]);
78         }
79         printf("Case %d:\n",++ccnt);
80         for(int i=1;i<=m;i++){
81             ask[i].limit=lower_bound(b+1,b+1+len,ask[i].limit)-b;
82             if(!ask[i].limit) printf("0\n");
83             else{
84                 int ans=query(1,len,Root[ask[i].l-1],Root[ask[i].r],ask[i].limit);
85                 printf("%d\n",ans);
86             }
87         }
88     }
89     return 0;
90 }

 

posted @ 2019-10-08 23:55  古比  阅读(129)  评论(0编辑  收藏  举报