[agc009e]Eternal Average

题目大意

给你n个0,m个1,和一个k。每次操作你选择k个数,擦去这k个数并加入他们的平均数(1个),问最后会有多少种不同的实数。
n,m,k<=2000,(k-1)|(n+m-1)

解题思路

转化一下题意。
考虑一种方案是一颗k叉树,给每个0和1安排深度,作为树的叶子节点,这些点的权值为0/1,其他点权值为所有儿子的平均数。问最后有多少种根节点权值不同的树。
现在问题稍微转化了一下,看起来舒服了一点。
考虑根节点的权值。我们只用考虑1的深度,权值为 i=1..mkdep1[i] ∑ i = 1.. m k − d e p 1 [ i ] .
考虑合法的树的条件。不妨把把0都变成1,最后根节点的权值一定为1。 1=i=1..mkdep1[i]+i=1..nkdep0[i] 1 = ∑ i = 1.. m k − d e p 1 [ i ] + ∑ i = 1.. n k − d e p 0 [ i ]
那么我们现在实际要求,有多少个不同的实数z,能够表示成m个k的次幂的和,且1-z能表示成n个k的次幂的和。
不妨把z搞成k进制数。那么原本同深度的点会进位,这就比较好看。
首先考虑z能够表示成m个数的和。
z=0.s1s2...sl z = 0. s 1 s 2 . . . s l ,其中s[l]≠0,那么 s[i]ms[i]%(k1)=m%(k1) ∑ s [ i ] ≤ m 且 ∑ s [ i ] % ( k − 1 ) = m % ( k − 1 ) ,其实就是把进位搞一搞。
还要考虑1-z。考虑1-z的长度肯定也是l,那么我们把n-=1,这样1-z的每一位和s[]加起来都是k-1了。类似的写出一样的式子,那么我们发现我们要求的东西是一个序列s[]的方案数,其中满足:对于所有 1il,s[i][0,k1] 1 ≤ i ≤ l , s [ i ] ∈ [ 0 , k − 1 ] ,且 s[l]0 s [ l ] ≠ 0 ,且满足上面写的关于n,m的式子。
然后用一个简单的dp做就可以了。

代码

#include<cstdio> 
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
using namespace std;
typedef long long ll;
typedef double db;
#define fo(i,j,k) for(i=j;i<=k;i++)
#define fd(i,j,k) for(i=j;i>=k;i--)
#define cmax(a,b) (a=(a>b)?a:b)
#define cmin(a,b) (a=(a<b)?a:b)
const int N=1e6+5,mo=1e9+7;
int n,m,K,i,j,k,q1,q2;
ll f[2][2005][2],sum[2005];
int ans;
int main()
{
    freopen("t12.in","r",stdin);
    scanf("%d %d %d",&n,&m,&K);
    m--;K--;
    q1=0;
    q2=1;
    f[0][0][0]=1;
    fo(i,1,max(n,m)*2)
    {
        fo(j,0,n) sum[j+1]=(sum[j-1+1]+f[q1][j][0]+f[q1][j][1])%mo;
        fo(j,0,n)
        {
            f[q2][j][0]=(sum[j+1]-sum[j-1+1])%mo;
            k=max(0,j-K);
            f[q2][j][1]=(sum[j-1+1]-sum[k-1+1])%mo;
        }
        fo(j,0,n)
            if (j%K==n%K&&(i*K-j)%K==m%K&&i*K-j<=m)
                ans=(ans+f[q2][j][1])%mo;
        q1^=1;q2^=1;
    }
    ans=(ans+mo)%mo;
    printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值