1. 程式人生 > >HDU 4417 Super Mario(主席樹)

HDU 4417 Super Mario(主席樹)

there mon ref seve pin ans ins Go follow

Super Mario

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8365 Accepted Submission(s): 3540


Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss’s castle as a line (the length is n), on every integer point i there is a brick on height hi. Now the question is how many bricks in [L, R] Mario can hit if the maximal height he can jump is H.

Input The first line follows an integer T, the number of test data.
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)

Output For each case, output "Case X: " (X is the case number starting from 1) followed by m lines, each line contains an integer. The ith integer is the number of bricks Mario can hit for the ith query.

Sample Input 1 10 10 0 5 2 7 5 4 3 8 7 7 2 8 6 3 5 0 1 3 1 1 9 4 0 1 0 3 5 5 5 5 1 4 6 3 1 5 7 5 7 3

Sample Output Case 1: 4 0 0 3 1 2 0 1 5 1

Source 2012 ACM/ICPC Asia Regional Hangzhou Online

Recommend liuyiding | We have carefully selected several similar problems for you: 6275 6274 6273 6272 6271 題意是求 區間[L,R]的小於等於h的數的個數 主席樹的模板題 代碼如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<vector>
using namespace std;
const int MAXN=1e5+10;
int a[MAXN],root[MAXN];
int t,n,m,l,r,x;
vector<int>v;
int get_id(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}  //因為每個數的範圍很大,需要進行離散化處理

struct node
{
  int l;
  int r;
  int h;
}qes[MAXN];

struct Node
{
   int l;
   int r;
   int sum;
}T[MAXN*40];
int cnt;
int ans;
void Update(int l,int r,int &x,int y,int pos)
{
   T[++cnt]=T[y],T[cnt].sum++,x=cnt;
   if(l==r)return;
   int mid=(l+r)>>1;
   if(pos<=mid)Update(l,mid,T[x].l,T[y].l,pos);
   else Update(mid+1,r,T[x].r,T[y].r,pos);
}

void query(int l,int r,int x,int y,int k)
{

    int mid=(l+r)>>1;
    if(mid==k)// 如果小於等於k的數剛好全部在左邊區域,加上它的權值,直接結束
    {
    ans+=T[T[y].l].sum-T[T[x].l].sum;
    return;
    }
    else if(k<mid) //左邊存在部分小於等於k的數,查詢左邊區域
    query(l,mid,T[x].l,T[y].l,k);
    else//右邊存在部分小於k的數,則加上左邊的權值,並查詢右邊區域。
    {
      ans+=T[T[y].l].sum-T[T[x].l].sum;
      query(mid+1,r,T[x].r,T[y].r,k);
    }
}

int main()
{
    scanf("%d",&t);
    int Case=0;
    while(t--)
    {
     Case++;
     cnt=0;
     v.clear();
     scanf("%d%d",&n,&m);
     for(int i=1;i<=n;i++)
     {
      scanf("%d",&a[i]);
      v.push_back(a[i]);
     }

      for(int i=1;i<=m;i++)
      {
         scanf("%d%d%d",&qes[i].l,&qes[i].r,&qes[i].h);
          v.push_back(qes[i].h);
      }
       sort(v.begin(),v.end());
       v.erase(unique(v.begin(),v.end()),v.end());



      int sz=v.size();
      for(int i=1;i<=n;i++)
      Update(1,sz,root[i],root[i-1],get_id(a[i]));

      printf("Case %d:\n",Case);
      for(int i=1;i<=m;i++)
      {
         ans=0;
         query(1,sz,root[qes[i].l],root[qes[i].r+1],get_id(qes[i].h));
         printf("%d\n",ans);
      }

    }
    return 0;
}

HDU 4417 Super Mario(主席樹)