[主席树]HDOJ4417 Super Mario

题意:n个数 m个询问  ($n、m \le 10^5$)

每个询问有l, r, k  问的是[l, r]区间内有多少个数小于等于k

 

用主席树做的话查询第i小的数与k比较即可

 

[主席树]HDOJ4417 Super Mario
  1 #define lson l, m

  2 #define rson m+1, r

  3 const int N=1e5+5;

  4 int L[N<<5], R[N<<5], sum[N<<5];

  5 int tot;

  6 int a[N], T[N], Hash[N];

  7 int build(int l, int r)

  8 {

  9     int rt=(++tot);

 10     sum[rt]=0;

 11     if(l<r)

 12     {

 13         int m=(l+r)>>1;

 14         L[rt]=build(lson);

 15         R[rt]=build(rson);

 16     }

 17     return rt;

 18 }

 19 

 20 int update(int pre, int l, int r, int x)

 21 {

 22     int rt=(++tot);

 23     L[rt]=L[pre], R[rt]=R[pre], sum[rt]=sum[pre]+1;

 24     if(l<r)

 25     {

 26         int m=(l+r)>>1;

 27         if(x<=m)

 28             L[rt]=update(L[pre], lson, x);

 29         else

 30             R[rt]=update(R[pre], rson, x);

 31     }

 32     return rt;

 33 }

 34 

 35 int query(int u, int v, int l, int r, int k)

 36 {

 37     if(l>=r)

 38         return l;

 39     int m=(l+r)>>1;

 40     int num=sum[L[v]]-sum[L[u]];

 41     if(num>=k)

 42         return query(L[u], L[v], lson, k);

 43     else

 44         return query(R[u], R[v], rson, k-num);

 45 }

 46 

 47 int main()

 48 {

 49     int t, ca=1;

 50     scanf("%d", &t);

 51     while(t--)

 52     {

 53         tot=0;

 54         int n, m;

 55         scanf("%d%d", &n, &m);

 56         for(int i=1; i<=n; i++)

 57         {

 58             scanf("%d", &a[i]);

 59             Hash[i]=a[i];

 60         }

 61         sort(Hash+1, Hash+n+1);

 62         int d=unique(Hash+1, Hash+n+1)-Hash-1;

 63         T[0]=build(1, d);

 64         for(int i=1; i<=n; i++)

 65         {

 66             int x=lower_bound(Hash+1, Hash+d+1, a[i])-Hash;

 67             T[i]=update(T[i-1], 1, d, x);

 68         }

 69         printf("Case %d:\n", ca++);

 70         while(m--)

 71         {

 72             int l, r, k;

 73             scanf("%d%d%d", &l, &r, &k);

 74             l++, r++;

 75             int ll=1, rr=r-l+1;

 76             int ans=0;

 77             while(ll<=rr)

 78             {

 79                 int mm=(ll+rr)>>1;

 80                 int tmp=Hash[query(T[l-1], T[r], 1, d, mm)];

 81                 if(tmp<=k)

 82                 {

 83                     if(mm==r-l+1 || Hash[query(T[l-1], T[r], 1, d, mm+1)]>k)

 84                     {

 85                         ans=mm;

 86                         break;

 87                     }

 88                     ll=mm+1;

 89                 }

 90                 else

 91                 {

 92                     if(mm==1 || Hash[query(T[l-1], T[r], 1, d, mm-1)]<=k)

 93                     {

 94                         ans=mm-1;

 95                         break;

 96                     }

 97                     rr=mm-1;

 98                 }

 99             }

100             printf("%d\n", ans);

101         }

102     }

103     return 0;

104 }
HDOJ 4417

 

你可能感兴趣的:(super)