F.Lucky Pascal Triangl(lucas+数位dp)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了F.Lucky Pascal Triangl(lucas+数位dp)相关的知识,希望对你有一定的参考价值。
在杨辉三角的前 n n n行中,有多少个数字是 7 7 7的倍数?
求 ∑ i = 1 n ∑ j = 1 i [ ( i j ) % 7 = = 0 ] \\sum\\limits_{i=1}^n \\sum\\limits_{j=1}^i[\\binom{i}{j}\\%7==0] i=1∑nj=1∑i[(ji)%7==0]
考虑卢卡斯定理, L u c a s ( i , j , p ) = ( i % p j % p ) ∗ L u c a s ( i / p , j / p , p ) % p Lucas(i,j,p)=\\binom{i\\%p}{j\\%p}*Lucas(i/p,j/p,p)\\%p Lucas(i,j,p)=(j%pi%p)∗Lucas(i/p,j/p,p)%p
然后注意到,这个过程相当于把 i , j i,j i,j在 p p p进制下的每一位拿出来做组合数
L u c a s ( i , j , p ) = ∏ ( i k j k ) % p Lucas(i,j,p)=\\prod \\binom{i_k}{j_k}\\%p Lucas(i,j,p)=∏(jkik)%p
注意到由于这里的 i k , j k < 7 i_k,j_k<7 ik,jk<7,所以形成的组合数不会包含因子 7 7 7
而最后想使 L u c a s ( i , j , p ) = 0 Lucas(i,j,p)=0 Lucas(i,j,p)=0只能是存在某一位 k k k满足 i k < j k i_k<j_k ik<jk
于是就是求这样的合法对 ( i , j ) (i,j) (i,j)满足 n > = i > j n>=i>j n>=i>j且存在 i k < j k i_k<j_k ik<jk
这个可以用数位 d p dp dp求
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int f[24][2][2][2],a[24];
int dfs(int len,int lim1,int lim2,int ok)
{
if( !len ) return ok;
if( f[len][lim1][lim2][ok]!=-1 ) return f[len][lim1][lim2][ok];
int las1 = lim1?a[len]:6; long long ans = 0;
for(int i=0;i<=las1;i++)
for(int j=0;j<=( lim2?i:6 );j++)
ans = ans+dfs( len-1,lim1&(i==las1),lim2&(j==i),ok|(i<j));
return f[len][lim1][lim2][ok] = ans%mod;
}
int solve(long long x)
{
memset( f,-1,sizeof f );
a[0] = 0;
while( x ) a[++a[0]] = x%7, x/=7;
return dfs( a[0],1,1,0 );
}
signed main()
{
ios::sync_with_stdio( false ); cin.tie( 0 ); cout.tie( 0 );
int t,casenum = 0; cin >> t;
while( t-- )
{
long long n; cin >> n;
cout << "Case " << ++casenum << ": " << solve( n ) << "\\n";
}
}
以上是关于F.Lucky Pascal Triangl(lucas+数位dp)的主要内容,如果未能解决你的问题,请参考以下文章