HDU--4417 Super Mario (主席树模版题)

题目链接

题目让求 L R区间 不大于H 的数有多少

数据太大需要离散化

#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
int a[maxn],root[maxn],tot,n,m;
vector<int>q;
struct ac{
   int va,l,r;
}tre[maxn*22];
void init(){
  memset(root,0,sizeof(root));
  memset(tre,0,sizeof(tre));
  tot=0;q.clear();
}
int getid(int x){
   return lower_bound(q.begin(),q.end(),x)-q.begin()+1;
}
void updata(int l,int r,int& x,int in,int z){
   tre[++tot]=tre[in];
   tre[tot].va++;
   x=tot;
   if(l==r) return ;
   int mid=(l+r)/2;
   if(z>mid){
       updata(mid+1,r,tre[x].r,tre[in].r,z);
   }else{
       updata(l,mid,tre[x].l,tre[in].l,z);
   }
}
int query(int x,int y,int l,int r,int z){
   if(x==y) return(tre[r].va-tre[l].va);
   int mid=(x+y)/2;
   if(z<=mid){
      return query(x,mid,tre[l].l,tre[r].l,z);
   }
   int ans=tre[tre[r].l].va-tre[tre[l].l].va;
   return (ans+query(mid+1,y,tre[l].r,tre[r].r,z));
}
int main(){
   int t,cnt=1;
   cin>>t;
   while(t--){
      scanf("%d%d",&n,&m);
      init();
      for(int j=1;j<=n;j++){
         scanf("%d",&a[j]);
         q.push_back(a[j]);
      }
      sort(q.begin(),q.end());
      q.erase(unique(q.begin(),q.end()),q.end());
      int len=q.size();
      for(int j=1;j<=n;j++){
         int x=getid(a[j]);
         updata(1,len,root[j],root[j-1],x);
      }
      printf("Case %d:
",cnt++);
      for(int j=0;j<m;j++){
         int l,r,k;
         scanf("%d%d%d",&l,&r,&k);
         l++,r++;
         int z=getid(k+1)-1;
         if(z)printf("%d
",query(1,len,root[l-1],root[r],z)); 
         else printf("0
");// 如果要查的数不在 a数组中直接输出0 k<min(an)
      }
   }
}
原文地址:https://www.cnblogs.com/Dvelpro/p/9769152.html