Codeforces 914H

Posted None

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 914H相关的知识,希望对你有一定的参考价值。

我这个低能儿怎么这个题调了这么久啊,废了/dk

非常烦的做法,不过也可以看看,代码也不算太难写(

首先注意到很诈骗的一件事情是,只要这个序列 \\(a\\) 是单峰的或者单谷的(当然,递增递减序列也算在内),都恰有两种方式选择 \\((i,op)\\) 使得操作完后的序列的单调的,并且显然选树的 Ember 有必胜策略(一条链显然合法),因此我们只用统计满足每个点度数都 \\(\\le d\\),并且任意两点间的路径都是单峰或单谷的树的数量即可。乘以 \\(2n(n-1)\\) 就是答案。

考虑两个比较特殊的点:\\(1\\)\\(n\\),显然如果 \\(1\\) 不是叶子,那么合法的必要条件是当以 \\(1\\) 为根时每个点的父亲编号都比它小。\\(n\\) 不是叶子的时候也是类似的。求解这一步考虑 \\(dp_i,j\\) 表示由 \\(i\\) 个点组成的子树个数,使得根节点儿子个数为 \\(j\\),且每个点编号都比其儿子小的方案数,转移考虑将每种 siz 的子树分开来加入,即从小到大枚举 \\(i\\),然后枚举大小为 \\(i\\) 的子树个数 \\(j\\)。记 \\(cnt_i=\\sum\\limits_j=0^d-1dp_i,j\\),那么容易算得 \\(dp_x,y\\to dp\'_x+ij,y+j\\) 的方案数为 \\(cnt_i^j·\\dbinomx+ijij·\\prod\\limits_k=1^j\\dbinomki-1i-1\\),预处理后面一大坨即可做到 \\(n^3\\ln n\\)

这样 \\(1,n\\) 中有一者不是叶子节点的方案数就能算了——为 \\(2f_n-2\\),之所以 \\(-2\\) 是因为要扣除一条链的情况。接下来考虑 \\(1,n\\) 都是叶子节点的情况,考虑这条链上的节点——一定是递增的,假设从左到右分别为 \\(1=a_0,a_1,a_2,\\cdots,a_k,a_k+1=n\\),再考虑与链上 \\(a_1\\sim a_k\\) 相连的子树,显然每个子树要么每个点编号都比其父亲大(称之为递增子树),要么每个点编号都比其父亲小(称之为递减子树),而且我们发现,不会出现两个点 \\(a_i,a_j(i<j)\\) 使得 \\(a_i\\) 连了一个递增子树,\\(a_j\\) 连了一个递减子树。只要不存在这样的情况,那么这棵树一定合法。

接下来考虑 DP。分两种情况,不存在一个点既连了递增子树也连了递减子树的情况,和存在一个点既连了递增子树也连了递减子树的情况。这里首先声明一下,我们先假设至少存在一个递增子树和递减子树,因为不存在递增子树和递减子树的情况我们已经在前面算过了。对于前者,考虑 \\(f_i,j\\) 表示链上前 \\(i\\) 个点连的子树之和为 \\(j\\) 的方案数,那么容易得到 \\(f_i,j=\\sum\\limits_k=1^jf_i-1,j-k·sdp_k-1,d-2·\\dbinomj-1k-1\\),其中 \\(sdp_i,j=\\sum\\limits_k=0^jdp_i,k\\)。发现 \\(i\\) 这一维可以去掉,因此下记 \\(f_j=\\sum\\limits_if_i,j\\)。然后考虑枚举左右部分的大小,设 \\(g_i\\) 表示钦定链上最后一个节点的子树大小必须 \\(\\ge 2\\) 的方案数,显然 \\(g_i=\\sum\\limits_j\\le i-2f_j·sdp_i-j-1,d-2·\\dbinomi-1j\\),这样我们假设 \\(a_i\\) 为最靠右的连了递减子树的点,\\(a_j\\) 为最靠左的连了递增子树的点,我们枚举 \\(i\\) 左边的 \\(siz=x\\)\\(j\\) 右边的 \\(siz=y\\),那么显然 \\(i\\) 左边只能填 \\(2\\sim x+1\\)\\(y\\) 右边只能填 \\(n-y\\sim n-1\\),中间就按顺序填呗,方案数 \\(g_i·g_j\\),于是这部分的答案为 \\(\\sum\\limits_i+j\\le n-2g_ig_j\\)。‘

考虑存在一个点既连了递增子树也连了递减子树的方案数。先考虑一个枚举量大一点的算法:枚举这个点左边的子树大小之和 \\(x\\),右边的大小之和 \\(y\\),连的递增子树的总大小 \\(p\\),递减子树的总大小 \\(q\\)(显然要求 \\(x+y+p+q=n-3\\)),连的递增子树的个数 \\(s\\),连的递减子树的个数 \\(t\\)(显然要求 \\(s+t\\le d-2\\)),那么方案数是 \\(f_xf_y\\dbinomx+px\\dbinomy+qydp_p,sdp_q,t\\),然后发现 \\(x,p,s\\) 是一组,\\(y,q,t\\) 是一组,设个 \\(h_i,s=\\sum\\limits_x+p=if_x\\dbinomx+pxdp_p,s\\) 即可做到三方枚举量。

总复杂度 \\(O(n^3\\ln n)\\),如果模数的 NTT 模数的话可能可以做到 \\(n^2\\log n\\ln n\\),不过没有必要。不知道如果 \\(p=998244353\\) 数据范围能否开大到 \\(10^5\\),反正我是不会,希望比我强的大佬能够给出一个答复。

const int MAXN=200;
int n,d;ll mod,c[MAXN+5][MAXN+5],way[MAXN+5][MAXN+5];
ll dp[MAXN+5][MAXN+5],sdp[MAXN+5][MAXN+5],f[MAXN+5],g[MAXN+5],h[MAXN+5][MAXN+5];
int main()
	scanf("%d%d%lld",&n,&d,&mod);
	if(d==1&&n>2)return puts("0"),0;
	for(int i=0;i<=n;i++)
		c[i][0]=1;
		for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
	
	for(int i=1;i<=n;i++)
		way[i][0]=1;
		for(int j=1;j*i<=n;j++)way[i][j]=1ll*way[i][j-1]*c[i*j-1][i-1]%mod;
	
	dp[0][0]=1;for(int i=0;i<=d;i++)sdp[0][i]=1;
	for(int i=1;i<n;i++)
		static ll tmp[MAXN+5][MAXN+5];
		for(int j=0;j<=n;j++)for(int k=0;k<=d;k++)tmp[j][k]=dp[j][k];
		for(int j=i;j<=n;j++)for(int l=1;l<=d;l++)
			for(int o=1,pw=sdp[i-1][d-1];o*i<=j&&o<=l;o++,pw=1ll*pw*sdp[i-1][d-1]%mod)
				tmp[j][l]=(tmp[j][l]+1ll*dp[j-o*i][l-o]*way[i][o]%mod*c[j][o*i]%mod*pw)%mod;
		for(int j=0;j<=n;j++)for(int k=0;k<=d;k++)dp[j][k]=tmp[j][k];
		for(int l=1;l<=d;l++)sdp[i][l]=(sdp[i][l-1]+dp[i][l])%mod;
	
	ll res=(2*sdp[n-1][d]+mod-1)%mod;f[0]=1;
	for(int j=1;j<=n-2;j++)for(int k=1;k<=j;k++)
		f[j]=(f[j]+1ll*f[j-k]*sdp[k-1][d-2]%mod*c[j-1][k-1])%mod;
	for(int j=0;j<=n-2;j++)for(int k=2;k+j<=n-2;k++)
		g[k+j]=(g[k+j]+1ll*f[j]*sdp[k-1][d-2]%mod*c[k+j-1][k-1])%mod;
	for(int i=1;i<=n-2;i++)for(int j=1;j<=n-2;j++)
		if(i+j<=n-2)res=(res+1ll*g[i]*g[j])%mod;
	for(int i=0;i<=n-2;i++)for(int j=1;j+i<=n-2;j++)for(int k=1;k<=d-2;k++)
		h[i+j][k]=(h[i+j][k]+1ll*f[i]*c[i+j][i]%mod*dp[j][k])%mod;
	for(int x=1;x<=d-2;x++)for(int y=1;y<=d-2;y++)if(x+y<=d-2)for(int i=1;i<=n-3;i++)
		res=(res+1ll*h[i][x]*h[n-3-i][y])%mod;
	printf("%lld\\n",res*n*(n-1)*2%mod);
	return 0;

codeforces#101194H. Great Cells(数学)

题目链接:

 

题意:

 

数据范围:

$1\leq |S| \leq 1000 000$

分析: 

 

AC代码:

#include<bits/stdc++.h>
#define ll long long
#define pic pair<int,char>
#define pii pair<int,int>
using namespace std;
const int maxn=3e5+7;
const int mod=1e9+7;
ll qpow(ll x,ll y)
    ll res=1;
    while(y)
        if(y&1)res=res*x%mod;
        x=x*x%mod;
        y/=2;
    
    return res;

int main()
   // cout<<qpow(2,10)<<endl;
    int T;
    scanf("%d",&T);
    for(int cn=1;cn<=T;cn++)
        int n,m,k;
        scanf("%d %d %d",&n,&m,&k);
        ll ans=qpow(k,n*m),res=0;
        for(int i=2;i<=k;i++)
            res=(res+qpow(i-1,n+m-2)*qpow(k,(n-1)*(m-1))%mod)%mod;
        ans=(ans+res*n*m%mod)%mod;
        printf("Case #%d: %lld\n",cn,ans);
    
    return 0;

  

以上是关于Codeforces 914H的主要内容,如果未能解决你的问题,请参考以下文章

如何看codeforces做了多少题

codeforces上怎么看测试数据

codeforces比赛后怎么看题解和答案

codeforces是啥?

codeforces Codeforces 650A Watchmen

CodeForces - 504A && CodeForces - 624C && CodeForces - 2B