Test instructions: give you an array of a[n], for each time the array establishes a full K-fork tree, for each node, if the value of the parent node is larger than the value of this node, then it is a violation point, the number of violations in the 1~n-1 under the full fork tree is counted.
An intuitive thought is violence, because the total K-fork tree when K is very large, in fact, the number of layers is particularly small, so the feeling of violence is possible. Note that the formula for the son of a fully K-fork under the V-node is:
k* (V-1) +2...kv+1, the formula for the corresponding parent node is (v+k-2)/k. The son's number is continuous, and if we can quickly find out the number of nodes in a contiguous numbered node for each node, we can quickly update the answer, but if you do this for each node, it's at least an O (n^2) level approach. Note that for a fully K-fork tree, only the inner node needs to be counted, and the leaf node is not required. For a full K-fork Tree of size n, the number of inner nodes is O (n/k), so the total number of internal nodes is n/1+n/2+n/3+...n/n-1, i.e. O (NLOGN).
Then there is a single question about how many numbers are smaller than V in a continuous interval. Here I have no idea of a good simple method, but a functional segment tree is a workaround. Root[i] Represents a segment tree created with the value of a[i]~a[n], and when I need to ask how many numbers are less than or equal to V for an interval [l,r], only query (ROOT[L],1,V)-query (root[r],1,v) is required. The spatial complexity is O (NLOGN), the time complexity is a single inquiry O (Logn), and the final total complexity is O (nlog^2 N)
#pragma warning (disable:4996) #include <cstdio> #include <cstring> #include <iostream> #include < algorithm> #include <cmath> #include <string> #include <vector> #include <queue>using namespace std; #define MAXN 200500#define maxc maxn*20int n;int a[maxn], b[maxn];int res[maxn];int root[maxn];int nsize;in T LC[MAXC], rc[maxc];int sum[maxc];int tot;int insert (int rt, int L, int R, int v) {int cur = tot++;if (L = = R) {Sum[cur] = SUM[RT] + 1;return cur;} int M = (l + R) >> 1;if (v <= M) {rc[cur] = rc[rt];lc[cur] = insert (Lc[rt], L, M, V);} Else{lc[cur] = Lc[rt];rc[cur] = insert (Rc[rt], M + 1, R, v);} Sum[cur] = Sum[lc[cur]] + sum[rc[cur]];return cur;} int query (int rt, int l, int r, int l, int r) {if (L = = L&&r = R) {return sum[rt];} int M = (l + R) >> 1;if (R <= M) {return query (Lc[rt], L, M, L, R);} else if (l>m) {return query (Rc[rt], M + 1, R, L, r);} Else{return query (Lc[rt], L, M, L, m) + query (Rc[rt], M + 1, R, M + 1, R);}} int MaiN () {while (CIN >> N) {for (int i = 1; I <= n; ++i) {scanf ("%d", A + i); B[i] = A[i];} Sort (b+1, B + n+1); nsize = Unique (b+1, B + n+1)-b;for (int i = 1; I <= n; ++i) {A[i] = Lower_bound (b + 1, B + nsize, a [i])-B + 1;} memset (res, 0, sizeof (res)), tot = 1;root[n + 1] = Tot;lc[tot] = Rc[tot] = Sum[tot] = 0;tot++;for (int i = n; i >= 1; I- -) {Root[i] = insert (Root[i + 1], 1, nsize, A[i]);} for (int k = 1; k <= n-1; ++k) {int maxbound = (n + k-2)/k;for (int v = 1; v <= maxbound; ++v) {int cnt = 0;int LBound = k* (V-1) + 2;int rbound = min (k*v + 1, n); cnt = query (Root[lbound], 1, nsize, 1, A[v]-1)-Query (Root[rbound+1] , 1, nsize, 1, A[v]-1); Res[k] + = CNT;}} for (int i = 1; I <= n-1; ++i) {if (i > 1) printf ("");p rintf ("%d", Res[i]);} Puts ("");} return 0;}
codeforces538f A Heap of heaps (functional segment tree)