主席树 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 }