BZOJ1902: Zju2116 Christopher
$n \leq 10^{100}$,问$C_n^m,0<=m<=n$有多少是质数$p \leq 1e7$的倍数。
一样,套高精度的题,只有战胜他才能鄙视他。
但是我TM被他鄙视了一上午!!!
好先冷静分析。用Lucas的观点看组合数,这里就是个明显的数位DP了,统计每一位时大于当前数、小于等于当前数的合法和不合法方案数,很简单的转移,详见代码。
被鄙视*1:方程抄错了。。
被鄙视*2:高精度乘单精度乘法写错了。。
当然这也不能怪我鬼知道他有乘零!
好吧怪我
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 //#include<vector> 6 //#include<queue> 7 //#include<time.h> 8 //#include<complex> 9 #include<algorithm> 10 #include<stdlib.h> 11 using namespace std; 12 13 int n; 14 #define maxn 1011 15 int a[maxn],mod,b[maxn],lb; char s[maxn]; int len; 16 17 #define LL long long 18 struct LLL 19 { 20 int a[111],len; 21 LLL() {memset(a,0,sizeof(a)); len=0;} 22 void operator = (int x) 23 { 24 len=0; 25 while (x) a[++len]=x%10000,x/=10000; 26 } 27 void operator = (const LLL &b) 28 { 29 len=b.len; 30 for (int i=1;i<=len;i++) a[i]=b.a[i]; 31 } 32 LLL operator * (int x) 33 { 34 LLL ans; 35 for (int i=1;i<=len;i++) 36 { 37 LL tmp=a[i]*1ll*x; 38 ans.a[i+1]+=(ans.a[i]+tmp)/10000; 39 ans.a[i]=(ans.a[i]+tmp)%10000; 40 } 41 ans.len=len; 42 while (ans.a[ans.len+1]) 43 { 44 ans.len++; 45 if (ans.a[ans.len]>=10000) ans.a[ans.len+1]+=ans.a[ans.len]/10000,ans.a[ans.len]%=10000; 46 } 47 while (ans.a[ans.len]==0 && ans.len>1) ans.len--; 48 return ans; 49 } 50 LLL operator + (const LLL &b) 51 { 52 LLL ans; 53 for (int i=1,to=max(len,b.len);i<=to;i++) 54 { 55 ans.a[i]+=a[i]+b.a[i]; 56 if (ans.a[i]>=10000) 57 { 58 ans.a[i+1]++; 59 ans.a[i]-=10000; 60 } 61 } 62 ans.len=max(len,b.len); 63 while (ans.a[ans.len+1]) ans.len++; 64 return ans; 65 } 66 void out() 67 { 68 printf("%d",a[len]); 69 for (int i=len-1;i>0;i--) 70 { 71 for (int j=1000;j>1;j/=10) if (a[i]<j) putchar('0'); 72 printf("%d",a[i]); 73 } 74 } 75 }f[maxn][2],g[maxn]; 76 77 int main() 78 { 79 scanf("%s%d",s+1,&mod); len=strlen(s+1); 80 for (int i=1;i<=len;i++) a[i]=s[len-i+1]-'0'; 81 lb=0; while (len) 82 { 83 int tmp=0; 84 for (int i=len;i;i--) {int now=a[i]; a[i]=(tmp*10+now)/mod; tmp=(tmp*10+now)%mod;} 85 for (;len && a[len]==0;len--); 86 b[++lb]=tmp; 87 } 88 f[1][0]=0; f[1][1]=b[1]+1; g[1]=mod-1-b[1]; 89 for (int i=2;i<=lb;i++) 90 { 91 f[i][0]=f[i-1][0]*(b[i]+1)+g[i-1]*b[i]; 92 f[i][1]=f[i-1][1]*(b[i]+1); 93 g[i]=(f[i-1][0]+f[i-1][1])*(mod-1-b[i])+g[i-1]*(mod-b[i]); 94 } 95 f[lb][0].out(); 96 return 0; 97 }