F-Lucky Pascal Triangle
issue是fw题解
下面代码TLE了,但是此题数位dp的思想非常值得学习
Lucas的过程相当于把n,mn,mn,m在p进制下的每一位拿出来做组合数
Lucas(n,m,p)=∏(nkmk)modp\text{Lucas}(n,m,p)=\prod \dbinom {n_k}{m_k} \bmod pLucas(n,m,p)=∏(mknk)modp
本题需要求
∑i=1n∑j=1i[(ij)mod7=0]\sum_{i=1}^{n}\sum_{j=1}^i[\dbinom {i}{j} \bmod 7=0] i=1∑nj=1∑i[(ji)mod7=0]
由于nk,mkn_k,m_knk,mk都小于7,组合数不可能包含7的,因此想让(nm)mod7=0\dbinom {n}{m}\bmod 7=0(mn)mod7=0 当且仅当∏(nkmk)mod7=0\prod \dbinom {n_k}{m_k} \bmod 7 =0∏(mknk)mod7=0 即存在nk>mkn_k>m_knk>mk因为此时(nkmk)=0\dbinom {n_k}{m_k}=0 (mknk)=0
#include<bits/stdc++.h>using namespace std;
const int mod=1e9+7;
using ll=long long;
ll n;
int a[24];
int f[24][2][2][2];
int dfs(int u,int lim1,int lim2,int ok)
{if(u<=0) return ok;if(f[u][lim1][lim2][ok]!=-1) return f[u][lim1][lim2][ok];int v1=lim1?a[u]:6;f[u][lim1][lim2][ok]=0;int ans=0;for(int i=0;i<=v1;i++)for(int j=0;j<=(lim2?i:6);j++)ans=(1ll*ans+dfs(u-1,lim1&(i==v1),lim2&(i==j),ok|(i<j)))%mod;return f[u][lim1][lim2][ok]=ans;
}
int solve(ll x)
{memset(f,-1,sizeof f);int cnt=0;while(x) a[++cnt]=x%7,x/=7;return dfs(cnt,1,1,0);
}
int main()
{ios::sync_with_stdio(false);cin.tie();cout.tie(0);int Tc;cin>>Tc;for(int ca=1;ca<=Tc;ca++){cin>>n;cout<<"Case "<<ca<<": "<<solve(n)<<'\n';}return 0;
}