Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //misaka and elaina will carry me to red
- #pragma GCC optimize("O3,unroll-loops")
- #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
- #include <iostream>
- #include <cmath>
- #include <utility>
- #include <cassert>
- #include <algorithm>
- #include <vector>
- #include <array>
- #include <cstdio>
- #include <cstring>
- #include <functional>
- #include <numeric>
- #include <set>
- #include <queue>
- #include <map>
- #include <chrono>
- #include <random>
- #define sz(x) ((int)(x.size()))
- #define all(x) x.begin(), x.end()
- #define pb push_back
- #define eb emplace_back
- #define kill(x, s) {if(x){ cout << s << "\n"; return ; }}
- #ifndef LOCAL
- #define cerr while(0) cerr
- #endif
- using ll = long long;
- using lb = long double;
- const lb eps = 1e-9;
- const ll mod = 1e9 + 7, ll_max = 1e18;
- //const ll mod = (1 << (23)) * 119 +1, ll_max = 1e18;
- const int MX = 500 +10, int_max = 0x3f3f3f3f;
- struct {
- template<class T>
- operator T() {
- T x; std::cin >> x; return x;
- }
- } in;
- using namespace std;
- ll dp[2][MX][MX*2][4];
- ll fac[MX*2], ifac[MX*2];
- int deg[MX];
- ll binpow(ll a, ll b = mod - 2){
- ll ans = 1;
- for(int i = 1; i<=b; i*=2ll){
- if(i&b) (ans *= a) %= mod;
- (a *= a) %= mod;
- }
- return ans;
- }
- void solve(){
- int n = in;
- int leaf = 0;
- kill(n == 1, 0);
- kill(n == 2, 1);
- fac[0] = 1;
- ifac[0] = 1;
- for(int i = 0; i<n; i++){
- deg[i] = in;
- if(deg[i] == 1) leaf++;
- }
- for(int i = 1; i<=n*2; i++){
- fac[i] = 1ll*i*fac[i-1]%mod;
- ifac[i] = binpow(fac[i]);
- }
- dp[0][0][0][0] = 1;
- int sum = 0;
- int r = 0;
- for(int i = 0; i<n; i++){
- for(int j = 0; j<=i; j++){
- for(int k = 0; k<=sum; k++){
- for(int h = 0; h<2; h++){
- for(int l = 0; l<4; l+=2){
- //add to left side
- ll v = dp[r][j][k][h + l];
- (dp[r^1][j+1][k + deg[i]][h + l] += ifac[deg[i]-1] * v%mod) %= mod;
- //add to right side
- (dp[r^1][j][k][h + l] += ifac[deg[i]-1] * v%mod) %= mod;
- if(deg[i] > 1){
- if (h == 0){
- // add as left tree endpoint
- (dp[r^1][j + 1][k + deg[i] - 1][1 + l] += ifac[deg[i] - 2] * v % mod) %= mod;
- }
- if(l == 0){
- //add as right tree endpoint
- (dp[r^1][j][k][h + 2] += ifac[deg[i] - 2] * v % mod) %= mod;
- }
- }
- }
- }
- }
- }
- r ^= 1;
- for(int j = 0; j<=n; j++){
- for(int k = 0; k<=2*n-2; k++){
- for(int hl = 0; hl<4; hl++){
- dp[r^1][j][k][hl] = 0;
- }
- }
- }
- sum += deg[i];
- }
- ll ans = 0;
- for(int j = 2; j<=n-2; j++){
- int t = min(j, n - j);
- ans += 1ll * t * fac[n - j - 2] % mod * fac[j - 2] % mod * dp[r][j][2 * j - 2][3] % mod;
- }
- ans %= mod;
- ll tot = fac[n-2];
- for(int i = 1; i<=n; i++){
- tot *= ifac[deg[i-1]-1];
- tot %= mod;
- }
- ans += 2ll*tot*leaf%mod;
- ans %= mod;
- cerr << ans << " " << tot << "\n";
- cout << ans*binpow(2ll*tot%mod)%mod << "\n";
- }
- signed main(){
- cin.tie(0) -> sync_with_stdio(0);
- int T = 1;
- //cin >> T;
- for(int i = 1; i<=T; i++){
- //cout << "Case #" << i << ": ";
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement