题解 [AGC009E] Eternal Average

传送门

一开始想把贡献拆成被操作了 i 次的数贡献 valki
然后就什么也不会了

正解首先需要一个神奇的转化
考虑每个操作方案都对应着一棵 k 叉树
其中有 n 个权值为 0 的叶子,有 m 个权值为 1 的叶子
其它每个非叶节点的权值是其儿子权值的平均值
这样根节点的权值就是最后剩下的那个数
考虑一棵 k 叉树合法的条件是什么
xi 为每个 0 节点的深度,yi 为每个 1 节点的深度
考虑若将所有 0 节点的权值改为 1,则根节点权值一定为 1
此时满足

(1k)xi+(1k)yi=1

容易发现这是必要条件
考虑其充分性
因为最后和为 1,考虑 k 进制小数的进位
发现每个深度的节点都完成了凑齐 k 个节点形成一个上层节点的过程
那么确实是充分的
那么现在一个根节点的权值 z 合法的条件就变成了:
z 可以被表示成 i=1n(1k)xi 的形式且 1z 可以被表示成 i=1m(1k)yi 的形式
z1z 好像反了但是没影响

  • 与固定分数 1k 的幂次相关的限制可以考虑 k 进制小数 DP?
    注意小数 DP 需要记录最后一位是不是 0

尝试对 zk 进制小数形式 0.z1z2zl(zl>0) 进行 DP
那么限制条件是什么呢?
如果不考虑进位有 zi=n,加上进位就是

zinzin(modk1)

nm 好像也反了但是问题不大
同理有

1+(kzi1)m1+(kzi1)m(modk1)

对这个东西大力小数 DP 即可
复杂度 O(n+m1k1nk)=O(n2)

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 4010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m, k;
const ll mod=1e9+7;
ll f[N][N][2], ans;

signed main()
{
	n=read(); m=read(); k=read();
	int lim=(n+m-1)/(k-1);
	f[0][0][0]=1;
	for (int i=0; i<=lim; ++i) {
		for (int j=0; j<=min((k-1)*i, n); ++j) {
			// if (f[i][j][0]) printf("f[%d][%d][%d]=%lld\n", i, j, 0, f[i][j][0]);
			// if (f[i][j][1]) printf("f[%d][%d][%d]=%lld\n", i, j, 1, f[i][j][1]);
			for (int t=0; t<k; ++t) {
				if (j+t<=n && 1+(i+1)*(k-1)-j-t<=m) f[i+1][j+t][t!=0]=(f[i+1][j+t][t!=0]+f[i][j][0]+f[i][j][1])%mod;
			}
		}
	}
	for (int i=1; i<=lim; ++i)
		for (int j=0; j<=min((k-1)*i, n); ++j)
			if (j%(k-1)==n%(k-1) && ((1-j)%(k-1)+(k-1))%(k-1)==m%(k-1))
				ans=(ans+f[i][j][1])%mod;
	printf("%lld\n", ans);
	
	return 0;
}
posted @   Administrator-09  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示