由于数字是递增的,一般有两个惯用套路来处理:
讲完了这些这题就瞬间会做了一半,我们设 c n t i cnt_i cnti表示长度 ≤ n leq n ≤n的连续的1模d余i的个数。由于n太大这东西不好直接算,但是我们手写几个数就会发现,这东西是有很明显的规律的:
首先开始是几个无序的数
之后随着1的个数的增加,会出现一段一段循环,往往这个循环节长度很小。
那么怎么找到这个循环节和前面无序数的长度呢?
我介绍两种方法:
有了 c n t cnt cnt数组,一切就变得豁然开朗。接下来考虑dp:
d p i , j 表 示 放 了 i 层 , 模 d = j 的 方 案 数 转 移 : d p i , j = ∑ d p i − k , j − k ∗ m ∗ C c n t m + k − 1 k dp_{i,j}表示放了i层,模d=j的方案数\ 转移:dp_{i,j}=sum dp_{i-k,j-k*m}*C_{cnt_m+k-1}^k dpi,j表示放了i层,模d=j的方案数转移:dpi,j=∑dpi−k,j−k∗m∗Ccntm+k−1k
Code:
/*
{AuThOr Gwj
*/
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(LL a=b;a<=c;++a)
#define rl(a,b,c) for(LL a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(LL a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin>>a
#define R2(a,b) cin>>a>>b
using namespace std;
const LL INF=0x3f3f3f3f;
typedef pair<LL,LL> mp;
/*}
*/
const int MOD=1e9+7;
class IncreasingNumber{vector<LL> cycle;
LL z[1000200];
LL cnt[500]={0};
void z_function(vector<LL>& S){LL len=S.size()-1;LL l,r;memset(z,0,sizeof(z));rb(i,2,len)if(S[i]!=S[i-1]) break;else z[2]++;l=2,r=z[2]+1;rb(i,3,len){if(i<=r){z[i]=z[i-(l)+1];z[i]=min(z[i],r-i+1);if(z[i]+i-1==r){LL ite=z[i]+1;rb(j,r+1,len){if(S[j]!=S[ite++]) break;z[i]++;}l=i,r=i+z[i]-1;}}else{LL ite=1;rb(j,i,len){if(S[j]!=S[ite++]) break;z[i]++;}l=i,r=i+z[i]-1;}}
}
LL ext_cnt[500]={0};
LL t=0;LL n,d;
LL calc_cycle(vector<LL>& cycle){//处理循环节
// cout<<"-------START-A-NEW-ONE------"<<endl;z_function(cycle);rb(i,2,700000){if(z[i]+i-1>=cycle.size()-1){return i-1;}}if(t<n){
// cout<<cycle[1]<<endl;ext_cnt[cycle[1]]++;}t++; ase(cycle.begin()+1);return calc_cycle(cycle);
}
LL quick(LL A,LL B){if(B==0) return 1;LL tmp=quick(A,B>>1);tmp*=tmp;tmp%=MOD;if(B&1){tmp*=A;tmp%=MOD; }return tmp;
}
LL inv(LL x){return quick(x,MOD-2);
}
LL dp[10][500];
LL c_(LL A,LL B){LL res=1;rb(i,1,B){res*=(A-i+1)%MOD;res%=MOD;}rb(i,1,B){res*=inv(i);res%=MOD;}return res;
}
LL c(LL A,LL B){return c_(A+B-1,B);
}
public:LL countNumbers(long long n2, LL d2){n=n2;d=d2;
// cout<<n%MOD<<endl;memset(dp,0,sizeof(dp));cycle.PB(0);cycle.PB(1%d);LL las=1,lastten=10%d;rb(i,2,1000000){cycle.PB(las=(las+lastten)%d);
// cout<<las<<endl;lastten*=10;lastten%=d;}LL len=calc_cycle(cycle);t=min(t,(LL)n);if(n-t>len){n-=t;LL rest=(n)%len;rb(i,1,len)cnt[cycle[i]]++;rep(i,d)cnt[i]*=(n)/len%MOD,cnt[i]%=MOD;rb(i,1,rest){cnt[cycle[i]]++;cnt[cycle[i]]%=MOD;}n+=t;}else{rb(i,1,n-t)cnt[cycle[i]]++,cnt[cycle[i]]%=MOD;}rep(i,d)cnt[i]+=ext_cnt[i],cnt[i]%=MOD;LL must_be=1,ten=10;if(n<=1000000){rb(i,2,n){must_be+=ten;must_be%=d;ten*=10;ten%=d;}}else{n-=t;n%=len;if(n==0) n=len;must_be=cycle[n];}dp[0][0]=1;LL res=0;LL tmp=0; rep(i,d){
// if(cnt[i]) cout<<i<<"-"<<cnt[i]<<endl;tmp+=cnt[i];tmp%=MOD;}cnt[must_be]--;cnt[must_be]+=MOD;cnt[must_be]%=MOD;rb(k,0,d-1){if(cnt[k])rl(i,7,0){rb(j,1,8-i){LL tmp=c(cnt[k],j);rb(div,0,d-1){dp[i+j][(div+j*k)%d]+=dp[i][div]*tmp%MOD;dp[i+j][(div+j*k)%d]%=MOD;} }}}rb(i,0,8){rb(j,1,9-i)res+=dp[i][(d-(LL)j*must_be%d)%d],res%=MOD;}return res;}
}solver;
/*
1311237 364
1311237 364
//*/
//int main(){
// LL n;
// int d;
// R2(n,d);
// int ansuntNumbers(n,d);
// printf("%dn",ans);
//}
本文发布于:2024-02-01 00:13:58,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170671763832420.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |