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; }