今天又是考试,然而早晨7:30考到中午12:30,没时间吃饭了。
然而并不会做题啊啊啊。

T1:
20180417小测

20180417小测
系数显然是组合数啊......
然后,模数不是质数?这不是拓展lucas裸题吗?
等等,拓展lucas,我只写过一遍诶......
看我大力出奇迹:
就是把模数先分解成p1^k1*p2^k2...的形式,然后我们在mod px^kx的情况下进行计算,最后再用互质的CRT合并即可。
mod px^kx的情况下怎么算?我们能把与px互质的阶乘计算出来,再单独计算阶乘中有px的多少次方。
然后互质的直接在mod px^kx下求逆元即可,非互质的直接次数加减。
然而考场上被卡常只有90......
代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define debug cout
 6 typedef long long int lli;
 7 using namespace std;
 8 const int maxn=4e5+1e2;
 9 
10 lli in[maxn],ans;
11 lli c[maxn],modc[maxn];
12 lli fac[maxn],tim[maxn];
13 lli dvs[maxn],tms[maxn],pows[maxn];
14 int n,mod,now,psnow,cnt;
15 
16 inline lli fastpow(lli base,lli tim,lli mod) {
17     lli ret = 1;
18     while(tim) {
19         if( tim & 1 ) ret = ret * base % mod;
20         if( tim >>= 1 ) base = base * base % mod;
21     }
22     return ret;
23 }
24 inline lli exgcd(lli a,lli b,lli& x,lli& y) {
25     if( !b ) return x = 1 , y = 0 , a;
26     lli ret = exgcd(b,a%b,y,x);
27     y -= a / b * x;
28     return ret;
29 }
30 inline lli inv(lli t,lli mod) {
31     static lli x,y;
32     exgcd(t,mod,x,y);
33     return ( x % mod + mod ) % mod;
34 }
35 inline void getcoprime(int x,int& retc,int& rett) {
36     retc = x , rett = 0;
37     while( ! ( retc % now ) ) retc /= now , ++rett;
38 }
39 inline void preseq() {
40     fac[0] = 1 , tim[0] = 0;
41     for(int i=1,c,t;i<=n;i++) {
42         getcoprime(i,c,t);
43         fac[i] = fac[i-1] * c % psnow , tim[i] = tim[i-1] + t;
44     }
45 }
46 inline void getdvs(int x) {
47     for(int i=2;(lli)i*i<=x;i++)
48         if( ! ( x % i ) ) {
49             dvs[++cnt] = i , pows[cnt] = 1;
50             while( ! ( x % i ) ) ++tms[cnt] , pows[cnt] *= i , x /= i;
51         }
52     if( x != 1 ) dvs[++cnt] = x , pows[cnt] = x , tms[cnt] = 1;
53 }
54 inline void cnow(int x,int& retc,int& rett) {
55     retc = fac[n-1] * inv(fac[x],psnow) % psnow * inv(fac[n-1-x],psnow) % psnow;
56     rett = tim[n-1] - tim[x] - tim[n-1-x];
57 }
58 inline void merge(int x,int fac,int tim) {
59     lli cur = (lli) fac * fastpow(now,tim,mod) % mod;
60     c[x] = ( c[x] + cur * ( mod / psnow ) % mod * inv( mod / psnow , psnow ) % mod ) % mod;
61 }
62 
63 
64 int main() {
65     scanf("%d%d",&n,&mod);
66     for(int i=1;i<=n;i++) scanf("%lld",in+i);
67     getdvs(mod);
68     for(int i=1;i<=cnt;i++) {
69         now = dvs[i] , psnow = pows[i] , preseq();
70         for(int j=0,c,t;j<n;j++) cnow(j,c,t) , merge(j,c,t);
71     }
72     for(int i=1;i<=n;i++) ( ans += in[i] * c[i-1] % mod ) %= mod;
73     printf("%lld\n",ans);
74     return 0;
75 }
View Code

相关文章:

  • 2021-08-11
  • 2021-06-07
  • 2022-01-20
  • 2021-12-20
  • 2021-10-29
  • 2021-12-30
  • 2021-12-30
猜你喜欢
  • 2022-01-21
  • 2021-12-28
  • 2021-08-10
  • 2021-11-10
  • 2022-02-07
  • 2021-05-28
  • 2021-06-13
相关资源
相似解决方案