主席树HDU4417

#include <bits/stdc++.h>

using namespace std;
const int maxn = (1e5+10)*20;
int tn,root[maxn],sum[maxn],lson[maxn],rson[maxn];
int x,y;
void update(int i ,int j,int l,int &r)
{
    r = ++tn;
    if(i==j){
        sum[r] = sum[l]+1;
        return;
    }
    lson[r] = lson[l];rson[r] = rson[l];
    int mid = i+j>>1;
    if(x <= mid)update(i,mid,lson[l],lson[r]);
    else update(mid+1,j,rson[l],rson[r]);
    sum[r] = sum[lson[r]]+sum[rson[r]];
}
int query(int i,int j,int l,int r)
{
    if(x>y)return 0;
    if(x<=i && y>=j)
        return sum[r]-sum[l];
    int mid = i+j>>1,ret = 0;
    if(x <= mid)ret += query(i,mid,lson[l],lson[r]);
    if(y>mid) ret += query(mid+1,j,rson[l],rson[r]);
    return ret;
}
int num[maxn],nn;
int a[maxn];
int main()
{
    int t,n,m;
    scanf("%d",&t);
    for(int cas = 1; cas <= t; cas++)
    {
        printf("Case %d:
",cas);
        scanf("%d%d",&n,&m);
        nn = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d",a+i);
            num[nn++] = a[i];
        }
        sort(num,num+nn);
        nn = unique(num,num+nn)-num;
        tn = 0;
        for(int i = 1; i <= n; i++)
        {
            //建树的时候用lower_bound 快速找到原数在离散化后的的排名
            x = lower_bound(num,num+nn,a[i])-num;
            update(0,nn-1,root[i-1],root[i]);
        }
        int a,b,c;
        while(m--){
            scanf("%d%d%d",&a,&b,&c);
            //二分快速找到离散后的范围
            //[0,c]
            x = 0; y = upper_bound(num,num+nn,c)-num-1;
            //[c,nn]
            //y = nn-1;x = lower_bound(num,num+nn,c)-num;
            printf("%d
",query(0,nn-1,root[a],root[b+1]));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/--lr/p/9792845.html