For the new year, Farmer John decided to give his cows a festive binary search tree (BST)!
To generate the BST, FJ starts with a permutation?a={a1,a2,…,aN}a={a1,a2,…,aN}?of the integers?1…N1…N, where?N≤300N≤300. He then runs the following pseudocode with arguments?11?and?N.N.
generate(l,r): if l > r, return empty subtree; x = argmin_{l <= i <= r} a_i; // index of min a_i in {a_l,...,a_r} return a BST with x as the root, generate(l,x-1) as the left subtree, generate(x+1,r) as the right subtree;
For example, the permutation?{3,2,5,1,4}{3,2,5,1,4}?generates the following BST:
4 / \ 2 5 / \ 1 3
Let?di(a)di(a)?denote the depth of node?ii?in the tree corresponding to?a,a,?meaning the number of nodes on the path from?aiai?to the root. In the above example,?d4(a)=1,d2(a)=d5(a)=2,d4(a)=1,d2(a)=d5(a)=2,?and?d1(a)=d3(a)=3.d1(a)=d3(a)=3.
The number of inversions of?aa?is equal to the number of pairs of integers?(i,j)(i,j)?such that?1≤i<j≤N1≤i<j≤N?and?ai>aj.ai>aj.?The cows know that the?aa?that FJ will use to generate the BST has exactly?KK?inversions?(0≤K≤N(N?1)2)(0≤K≤N(N?1)2). Over all?aa?satisfying this condition, compute the remainder when?∑adi(a)∑adi(a)?is divided by?MM?for each?1≤i≤N.1≤i≤N.
The only line of input consists of three space-separated integers?N,K,N,K,?and?MM, followed by a new line.?MM?will be a prime number in the range?[108,109+9].[108,109+9].
Print?NN?space-separated integers denoting?∑adi(a)(modM)∑adi(a)(modM)?for each?1≤i≤N.1≤i≤N.
3 0 192603497
1 2 3
Here, the only permutation is?a={1,2,3}.a={1,2,3}.
3 1 144408983
3 4 4
Here, the two permutations are?a={1,3,2}a={1,3,2}?and?a={2,1,3}.a={2,1,3}.
Problem credits: Yinzhan Xu
<h3>USACO 2019 December Contest, Platinum Problem 3. Tree Depth 题解(翰林国际教育提供,仅供参考)</h3>
<p style="text-align: center;">题解请<a href="/register" target="_blank" rel="noopener">注册</a>或<a href="/login" target="_blank" rel="noopener">登录</a>查看</p>
[/hide]
(Analysis by Benjamin Qi)
For?N≤20,N≤20,?any reasonable polynomial-time solution should work. One possible approach is to calculate the result for all?n≤N,k≤(n2)n≤N,k≤(n2)?in?O(N7).O(N7).
For additional points, we should find a way to compute?di(a)di(a)?without explicitly constructing the tree. The key condition is that?jj?is an ancestor of?ii?if?a[j]=min(a[i…j]),a[j]=min(a[i…j]),?so it follows that
Let's focus on counting the number of permutations?aa?such that?a[j]==min(a[i…j])a[j]==min(a[i…j])?for some fixed pair?(i,j)(i,j)?satisfying?i<j.i<j.?We'll do this by constructing?aa?one element at a time.
First, we start with a sequence consisting of?a[i]a[i]?only. Then?a[i+1]a[i+1]?can be either greater than?a[i]a[i]?or less than?a[i],a[i],?contributing?00?or?11?inversion. Then?a[i+2]a[i+2]?can take on any of three different values relative to?a[i]a[i]?and?a[i+1],a[i+1],?contributing anywhere from?00?to?22?inversions. Continuing in this fashion, the possible numbers of inversions in the sub-permutation?a[i…j?1]a[i…j?1]?can be represented by the polynomial product
This is known as a?generating function?because we are encoding a sequence using a polynomial. If we expand it and group together the terms with the same power of?x,x,?then a term in the form?cxdcxd?means that there are exactly?cc?permutations with?dd?inversions.
Adding?a[j]a[j]?contributes?j?ij?i?inversions regardless of how many inversions?a[i…j?1]a[i…j?1]?has. Then we should add the remaining elements of the permutation, each of which can go anywhere in the sorted order. Thus, the final result is given by the generating function
The first part of this product does not depend on?ii?or?j,j,?and we can calculate it in?O(N3)O(N3)?time with prefix sums. We can divide it by?∑j?iu=0xu∑u=0j?ixu?in?O(N2)O(N2)?time by reversing the process we used to multiply.
After dividing, all we need is the coefficient of?xk?(j?i).xk?(j?i).?Since the product depends only on?j?i,j?i,?we only need to do?NN?different divisions. Alternatively, we can maintain prefix and suffix products without needing to do division. The process for?i>ji>j?is almost exactly the same, except?a[j]a[j]?contributes?00?inversions rather than?i?j.i?j.
The whole solution runs in?O(N3)O(N3)?time and?O(N2)O(N2)?memory. My code follows. It turns out that?MM?being prime is irrelevant ...
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> vi; #define FOR(i,a,b) for (int i = (a); i < (b); ++i) #define F0R(i,a) FOR(i,0,a) #define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i) #define R0F(i,a) ROF(i,0,a) #define trav(a,x) for (auto& a: x) #define pb push_back #define rsz resize #define sz(x) int(x.size()) void setIO(string name) { ios_base::sync_with_stdio(0); cin.tie(0); freopen((name+".in").c_str(),"r",stdin); freopen((name+".out").c_str(),"w",stdout); } int MOD; int n,k; typedef int T; struct mi { T val; mi() { val = 0; } mi(const ll& v) { val = (-MOD <= v && v <= MOD) ? v : v % MOD; if (val < 0) val += MOD; } mi& operator+=(const mi& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; } mi& operator-=(const mi& m) { if ((val -= m.val) < 0) val += MOD; return *this; } }; typedef vector<mi> vmi; void ad(vmi& a, int b) { // multiply by (x^0+x^1+...+x^{b-1}) a.rsz(sz(a)+b-1); R0F(i,sz(a)-b) a[i+b] -= a[i]; FOR(i,1,sz(a)) a[i] += a[i-1]; } void sub(vmi& a, int b) { ROF(i,1,sz(a)) a[i] -= a[i-1]; F0R(i,sz(a)-b) a[i+b] += a[i]; a.rsz(sz(a)-b+1); } mi get(vmi& a, int b) { if (b < 0 || b >= sz(a)) return 0; return a[b]; } int main() { setIO("treedepth"); cin >> n >> k >> MOD; vmi v = {1}; FOR(i,1,n+1) ad(v,i); vmi ans(n,v[k]); FOR(dif,1,n) { sub(v,dif+1); mi x = get(v,k-dif), y = get(v,k); ad(v,dif+1); F0R(a,n-dif) { ans[a] += x; ans[a+dif] += y; } } F0R(i,n) cout << ans[i].val << ' '; }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1