P4349 [CERC2015]Digit Division 思維題 數論
阿新 • • 發佈:2020-09-16
題意:
有一個\(N\)位的數字,將其分割,保證每個區間裡的數字可以被\(M\)整除,輸出方案數,答案對\(10^9+7\)取模
範圍&性質:\(1\le N\le 3\times10^5,1\le M\le 10^6\)
分析:
第一眼\(O(n^2)\)DP,一看資料範圍,放棄。思考怎麼優化,我們發現對於DP來說,每一個點都是由之前能夠斷開的地方轉移而來,那麼影響答案的只有可劃分的間隔,所以\(O(n)\)的掃一遍記錄能夠斷開的區間個數,且兩個斷點之間的區間一定能被\(M\)整除,最後只需要判斷一下最後一段區間能否被\(M\)整除,若可以,那麼答案就是$ 2^{斷點個數} $
程式碼:
#include<bits/stdc++.h> using namespace std; namespace zzc { const int mod = 1e9+7; const int maxn = 3e5+5; char ch[maxn]; int n,m,cnt=0,tmp=0; long long qpow(int x,int y) { long long res=1; while(y) { if(y&1) res=res*x%mod; x=(long long)x*x%mod; y>>=1; } return res; } void work() { scanf("%d%d",&n,&m); scanf("%s",ch+1); for(int i=1;i<n;i++) { tmp=(tmp*10+ch[i]-'0')%m; if(!tmp) { cnt++; } } tmp=(tmp*10+ch[n]-'0')%m; if(tmp) { printf("0\n"); return ; } else printf("%lld",qpow(2,cnt)); } } int main() { zzc::work(); return 0; }