Magical Chairman of the tree --Just h-index

Topic Portal: https://ac.nowcoder.com/acm/contest/1107/C

 

The meaning of problems: a given interval, the maximum required h, such that h is greater than the number at least equal to h interval.

 

Ideas: 1 range needs orderly, then you need to use the Chairman of the tree.

   2. dichotomous answer.

    2.1 - my initial idea is to directly answer each query-half h.

        Then determines whether the first len ​​(section number) -h + 1 is greater than equal to a small h, so two stars maximum h, but the T.

        First thought is often a card, so a variety of  Sao operation  or use no eggs.

        So in an optimization after the "n can be removed due to the small discrete", is still the T. Suddenly found direct-half position, that is, to find the answer directly to the Chairman of the tree directly in the query.

    2.2 - In the query process, we will continue to half position to determine that:

        Chairman of the tree,

        If the number is greater than the right h h, if it is, then go to the right subtree, otherwise the left sub-tree walk.

        Remember not discrete, because we dichotomy is the location, not the size.

 

//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize(2)
#include <bits/stdc++.h>

using namespace std;
typedef double dou;
typedef long long ll;
typedef pair<int, int> pii;
typedef map<int, int> mii;

#define pai acos(-1.0)
#define M 4000005
#define inf 0x3f3f3f3f
#define mod 1000000007
#define IN inline
#define W(a) while(a)
#define lowbit(a) a&(-a)
#define left k<<1
#define right k<<1|1
#define lson L, mid, left
#define rson mid + 1, R, right
#define ms(a,b) memset(a,b,sizeof(a))
#define Abs(a) (a ^ (a >> 31)) - (a >> 31)
#define random(a,b) (rand()%(b+1-a)+a)
#define false_stdio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

int n, cnt, Q;
int  num[M];
int T[M], Ls[M], Rs[M], sum[M];

IN int Built(int L, int R) {
    int rt = ++cnt;
    if (L < R) {
        int mid = (L + R) >> 1;
        Ls[rt] = Built(L, mid);
        Rs[rt] = Built(mid + 1, R);
    }
    return rt;
}

IN int updata(int L, int R, int pre, int id) {
    int rt = ++cnt;
    Ls[rt] = Ls[pre], Rs[rt] = Rs[pre], sum[rt] = sum[pre] + 1;
    if (L < R) {
        int= MID (L + R & lt) >> . 1 ;
         IF (ID <= MID) Ls of [RT] = UPDATA (L, MID, Ls of [pre], ID);
         the else Rs of [RT] = UPDATA (MID + . 1 , R & lt , Rs of [pre], ID); 
    } 
    return RT; 
} 


// Rtot is the number of the right child is a node on 
the iN int Query ( int U, int V, int L, int R & lt, int Rtot is) {
     IF ( R & lt == L) return L;
     int R_SUM = SUM [Rs of [V]] - SUM [Rs of [U]]; // the right number of child nodes 
    int MID = (L + R & lt) >> . 1;
    //判定条件
    if (mid - Rtot + 1 > R_sum)return query(Ls[u], Ls[v], L, mid, Rtot + R_sum);
    else return query(Rs[u], Rs[v], mid + 1, R, Rtot);
}

IN int read() {//读入挂
    int x = 0; bool f = 0; char ch = getchar();
    while (ch < '0' || '9' < ch)
        f |= ch == '-', ch = getchar();
    while ('0' <= ch && ch <= '9')
        x = x * 10 + ch - '0', ch = getchar();
    return f ? -x : x;
}

int main() {
    W(scanf("%d%d", &n, &Q) != EOF) {
        cnt = 0;
        T[0] = Built(1, n);
        for (register int i = 1; i <= n; i++)num[i] = read();
        for (register int i = 1; i <= n; i++)T[i] = updata(1, n, T[i - 1], num[i]);

        int l, r;
        W(Q--) {
            l = read(), r = read();
            printf("%d\n", query(T[l - 1], T[r], 1, n, 0));
        }
    }
    return 0;
}

 

        

Guess you like

Origin www.cnblogs.com/caibingxu/p/11617819.html