1. 程式人生 > >hdu 4417 劃分樹

hdu 4417 劃分樹

Super Mario

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


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

題意:

查詢指定區間內比x小的數的個數

思路:

稍微修改下劃分樹,但是不知道為什麼一開始想的是二分- -,強行GG。寫著很麻煩而且還是錯的

劃分數能很方便地求出了區間中小於等於第i個數的個數,在這個基礎上稍作修改即可

/*
*/

#include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <Map>
using namespace std;
typedef long long ll;
typedef long double ld;

using namespace std;

const int maxn = 100010;

int tree[20][maxn];
int sorted[maxn];
int toleft[20][maxn];

void build(int l,int r,int dep)  //模擬快排 並記錄左樹中比i小的個數
{
    if(l == r)
        return;
    int mid = (l+r)>>1;
    int same = mid-l+1;
    for(int i = l; i <= r; i++)
    {
        if(tree[dep][i] < sorted[mid])
            same--;
    }
    int lpos = l;
    int rpos = mid+1;
    for(int i = l; i <= r; i++)
    {
        if(tree[dep][i] < sorted[mid])
        {
            tree[dep+1][lpos++] = tree[dep][i];
        }
        else if(tree[dep][i] == sorted[mid] && same > 0)
        {
            tree[dep+1][lpos++] = tree[dep][i];
            same --;
        }
        else
        {
            tree[dep+1][rpos++] = tree[dep][i];
        }
        toleft[dep][i] = toleft[dep][l-1] + lpos -l;

    }
    build(l,mid,dep+1);
    build(mid+1,r,dep+1);
}


int query(int L,int R,int l,int r,int dep,int k)
{
    if(l == r)
    {
        if(tree[dep][l] <= k)
            return 1;
        return 0;
    }
    int mid = (L+R)>>1;
    int cnt = toleft[dep][r]-toleft[dep][l-1];
    if(sorted[mid] > k)          //如果比分界線小
    {
        int lpos = L+toleft[dep][l-1]-toleft[dep][L-1];
        int rpos = lpos+cnt-1;
        if(rpos >= lpos)
            return query(L,mid,lpos,rpos,dep+1,k);
        return 0;
    }
    else
    {
        int rpos = r+toleft[dep][R]-toleft[dep][r];
        int lpos = rpos-(r-l-cnt);
        return cnt+query(mid+1,R,lpos,rpos,dep+1,k);
    }
}


int main()
{
    int n,m,T;
    int cas = 1;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d",&sorted[i]);
            tree[0][i] = sorted[i];
        }
        sort(sorted+1,sorted+n+1);
        build(1,n,0);

        int l,r,to,ans;
        printf("Case %d:\n",cas++);
        while(m--)
        {
            scanf("%d%d%d",&l,&r,&to);
            l++;
            r++;
            ans = query(1,n,l,r,0,to);
            printf("%d\n",ans);
        }
    }
    return 0;
}


相關推薦

HDU 4417 劃分寫法

des eve else eight url ted nta namespace pan Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ab

hdu 4417 劃分

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4041    Accepted S

hdu 4417 主席

解題思路:將陣列去重離散化,建成一顆線段樹,那麼我們只要去找H的排名就可以用第r顆樹減去第l顆樹的(0-H)的區間數就可以了 #include<bits/stdc++.h> #define lson l,mid #define rson mid+1,r us

HDU 4251 劃分

/* 劃分樹:解題型別單一,給出10^5個點,給你 q 個查詢,每次查詢出[l,r] 中第 k 大的值。 劃分樹:                                 主系列  4 3 2 5 8 7 6 1 9                        

HDU 4417 Super Mario (狀陣列+離線處理)(劃分+二分答案)

題意: 給定1--n區間,有q個詢問,詢問l,r,k表示區間[l,r]小於等於k的數的個數 思路: 可以用劃分樹(求區間第k大值)變形一下,來求小於等於k的個數,但是此題直接離線處理詢問高效的多。 首先將1--n區間的值記錄位置,從小到大排序,每個詢問按照k值從小到大排序,

hdu 4417 2012杭州網路賽 劃分

劃分樹,對區間進行二分求 第mid 大的數 並且和 H比較即可。。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> usin

HDU 4417 (離線線段 || 劃分

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6291    Accepted S

HDU 4417 Super Mario--離線狀陣列、劃分、線段

題意:詢問區間[l,r]內有幾個數字小於h 思路:對於每次詢問H,L,R,僅需要考慮比H小的hi在L,R範圍內的個數;    為了避免比H大的hi的影響,可以想到對詢問H,和hi進行排序    在詢問H時,僅將比H小的hi插入到樹狀陣列中 #include<

hdu 2665 Kth number(劃分

first con build 這一 cst second class stream tom Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth

狀數組+離線查詢)HDU 4417 - Super Mario

blog 數組 string 個數 r++ dex 分塊 每次 class 題意: 給定一個數列,最多10萬次查詢l到r不超過h的數字的個數。 分析: 唉,太菜啦。 在線做法應該比較明顯,區間維護平衡樹,用線段樹套平衡樹,或者分塊套平衡樹,應該都能A,但是沒試

[hdu 4417]狀數組+離散化+離線處理

style code upper unique opera 鏈接 ems ons back 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 把數字離散化,一個查詢拆成兩個查詢,每次查詢一個前綴的和。主要問題是這個數組是

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)T

hdu 3473 (劃分)2

mage def typedef sin else BE IT ext cati Minimum Sum Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

HDU - 4417 Super Mario 主席

數量 \n make In printf ons bound update ket 題意:   給一個數列$\{ a_i \}$,一些詢問$(l_i,r_i,h_i)$,求$j\in [l_i,r_i] ,a_j<=h_i$的元素數量 題解:   問區間內$<=

hdu 4417 Super Mario (主席

代碼 i++ uil 我們 php amp build iostream sort 鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 題意: 給你段長為n的序列,有q個詢問,每次詢問區間[l.r]內有多少個數小於等於k

HDU 4417.Super Mario-無修改區間小於等於H的數的個數-可持久化線段

url java ios else string mes clu ber lower Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot

Super Mario HDU - 4417 (主席

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

HDU】2665Kth number(劃分

只是為了存模板~ #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 100005; int n,m;

劃分基礎 —— HDU 2665 Kth number

The first line is the number of the test cases.  For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number

hdu 2665 Kth number(劃分模板題)

題意:給定一個長度為n的序列,進行m次查詢,求出區間[l,r]中的第k大值。 思路:劃分樹模板題。上學的時候做過這道題,當時看了下劃分樹的講解,看得很頭大,然後就一直放著了。十一回家的時候在高鐵上沒什麼事情,就重新學習了一遍劃分樹。 劃分樹是通過模擬快速排序,記錄快速排序的