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:\n",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\n",query(1,len,root[l-1],root[r],z)); else printf("0\n");// 如果要查的数不在 a数组中直接输出0 k<min(an) } } }