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 }
View Code

 

posted @ 2018-03-21 12:38  Blue233333  阅读(229)  评论(0编辑  收藏  举报