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]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1