Super Mario
题意:
求【l,r】区间内小于等于k的数的个数。
分析:
首先考虑简单版,求【1,n】区间小于等于k的个数,如果一个数出现一次,就把对应的sum【rt】++,最后用线段树求一下【1,k】区间的sum之和就好了。所以我们可以用主席树来存储历史版本的线段树,然后对【l,r】区间对应的线段树求【1,k】区间的sum之和。
代码:

#include <map> #include <queue> #include <vector> #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) #define lson l,m #define rson m+1,r const int maxn=1e5+100; const int inf=0x3f3f3f3f; int n,m,tot,Case; int a[maxn],Hash[maxn]; int L[maxn<<2],R[maxn<<2],T[maxn<<2],sum[maxn<<2]; int build(int l,int r) { int rt=tot++; sum[rt]=0; if(l<r){ int m=(l+r)>>1; L[rt]=build(lson); R[rt]=build(rson); } return rt; } int update(int pre,int l,int r,int x) { int rt=tot++; L[rt]=L[pre]; R[rt]=R[pre]; if(l==r){ sum[rt]=sum[pre]+1; return rt; } int m=(l+r)>>1; if(x<=m) L[rt]=update(L[pre],lson,x); else R[rt]=update(R[pre],rson,x); sum[rt]=sum[L[rt]]+sum[R[rt]]; return rt; } int query(int u,int v,int ql,int qr,int l,int r) { if(ql<=l&&r<=qr){ return sum[v]-sum[u]; } int ans=0; int m=(l+r)>>1; if(ql<=m) ans+=query(L[u],L[v],ql,qr,lson); if(qr>m) ans+=query(R[u],R[v],ql,qr,rson); return ans; } int binarySearch(int key,int* a,int n) { if(a[1]>key) return -1; if(a[n]<key) return n; int l=1,r=n; while(l<=r) { int mid=(l+r)>>1; if(a[mid]==key) return mid; if(a[mid]>key&&a[mid-1]<key) return mid-1; else if(a[mid]<key) l=mid+1; else r=mid-1; } return -1; } int main() { // freopen("in.txt","r",stdin); scanf("%d",&Case); for(int t=1;t<=Case;t++){ tot=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); Hash[i]=a[i]; } sort(Hash+1,Hash+n+1); int d=1; for(int i=2;i<=n;i++){ if(Hash[i]!=Hash[i-1]) Hash[++d]=Hash[i]; } T[0]=build(1,d); for(int i=1;i<=n;i++){ int x=binarySearch(a[i],Hash,d); T[i]=update(T[i-1],1,d,x); } printf("Case %d: ",t); for(int i=1;i<=m;i++){ int l,r,k; scanf("%d%d%d",&l,&r,&k); l++,r++; k=binarySearch(k,Hash,d); if(k==-1){ printf("0 "); continue; } int p=query(T[l-1],T[r],1,k,1,d); printf("%d ",p); } } return 0; }