zoukankan      html  css  js  c++  java
  • 单位根反演学习笔记

    emm...原来反演公式有这么多呀。。。

    不多说了,直接进入正题。


    $$f(x)=\sum_{i=0}^na_ix^i\Rightarrow \sum_{i=0}^na_i[i\ mod \ k=0]=\frac{1}{k}\sum_{i=0}^{k-1}f(w_k^i)$$

    我们考虑证明这个式子。

    首先,有一个显而易见的引理。

    $$[i \ mod \ k=0]=\frac{1}{k}\sum_{j=0}^{k-1}w_k^{ij}$$

    这个式子用等比数列求和公式搞一下就出来了,就不多讲了。

    $$\sum_{i=0}^na_i[i \ mod \ k=0]=\frac{1}{k}\sum_{i=0}^n\sum_{j=0}^{k-1}a_iw_k^{ij}=\frac{1}{k}\sum_{j=0}^{k-1}\sum_{i=0}^na_i(w_k^j)^i=\frac{1}{k}\sum_{j=0}^{k-1}f(w_k^j)$$

    证毕。


    loj6485

    题目描述:求$$\sum_{i=0}^nC_n^is^ia_{i\bmod 4} \bmod 998244353$$


    首先$$ans=\sum_{j=0}^3a_j\sum_{i=0}^nC_n^is^i[i\bmod 4=j]$$

    先考虑$j=0$的时候,构造$f(x)=\sum_{i=0}^nC_n^is^ix^i=(sx+1)^n$

    所以$$\sum_{i=0}^nC_n^is^i[i\bmod 4=0]=\frac{1}{4}\sum_{j=0}^3f(w_4^j)$$

    但是当$j>0$的时候怎么办呢?我们考虑将$f(x)$乘上$x^{-j}$,就可以让模4余$j$的移到模4余0的位置了。

    综上$$ans=\frac{1}{4}\sum_{j=0}^3f(w_4^j)\sum_{i=0}^3a_iw_4^{-ij}$$

     1 #include<cstdio>
     2 #define Rint register int
     3 using namespace std;
     4 typedef long long LL;
     5 const int mod = 998244353, inv4 = 748683265;
     6 int t;
     7 LL n, s, a[4], w[4];
     8 inline LL kasumi(LL a, LL b){
     9     LL res = 1;
    10     while(b){
    11         if(b & 1) res = res * a % mod;
    12         a = a * a % mod;
    13         b >>= 1;
    14     }
    15     return res;
    16 }
    17 int main(){
    18     scanf("%d", &t);
    19     w[0] = 1; w[1] = kasumi(3, (mod - 1) >> 2); w[2] = w[1] * w[1] % mod; w[3] = w[1] * w[2] % mod;
    20     while(t --){
    21         scanf("%lld%lld", &n, &s); n %= mod - 1;
    22         for(Rint i = 0;i < 4;i ++) scanf("%lld", a + i);
    23         LL ans = 0;
    24         for(Rint j = 0;j < 4;j ++){
    25             LL tmp = kasumi((s * w[j] + 1) % mod, n);
    26             for(Rint i = 0;i < 4;i ++)
    27                 ans = (ans + tmp * a[i] % mod * w[(4 - i * j % 4) % 4]) % mod;
    28         }
    29         printf("%lld\n", ans * inv4 % mod);
    30     }
    31 }

    bzoj3328

    题目描述:求$$\sum_{i=0}^nC_n^iF_i[i\bmod k=0]$$

    其中$F_i$表示斐波那契数列的第$n$项。


    我们构造矩阵$$\begin{gather*}A=\begin{bmatrix}1 & 1 \\ 1 & 0\end{bmatrix}\end{gather*}$$

    大家对它应该很熟悉了,它就是斐波那契数列的转移矩阵。

    显然$$\begin{gather*}F_i=A^i*\begin{bmatrix}1 \\ 0\end{bmatrix}=A^i_{1,1}\end{gather*}$$

    然后构造生成函数$$f(x)=\sum_{i=0}^nC_n^iA^ix^i=(xA+I)^n$$

    $$Ans=\sum_{i=0}^nC_n^iA^i[i\bmod k=0]=\frac{1}{k}\sum_{j=0}^{k-1}f(w_k^j)$$

    这个矩阵的左上角就是答案。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #define Rint register int
     5 using namespace std;
     6 typedef long long LL;
     7 int t, k, p, g;
     8 vector<int> fac;
     9 LL n;
    10 inline int mul(int a, int b){return (LL) a * b - (LL) a * b / p * p;}
    11 inline int add(int a, int b){int res = a + b; if(res >= p) res -= p; return res;}
    12 struct Matrix {
    13     int a[2][2];
    14     inline Matrix(){memset(a, 0, sizeof a);}
    15     inline Matrix operator = (const Matrix &o){
    16         memcpy(a, o.a, sizeof a);
    17         return *this;
    18     }
    19     inline Matrix operator * (const Matrix &o) const {
    20         Matrix res;
    21         for(Rint i = 0;i < 2;i ++)
    22             for(Rint k = 0;k < 2;k ++)
    23                 for(Rint j = 0;j < 2;j ++)
    24                     res.a[i][j] = add(res.a[i][j], mul(a[i][k], o.a[k][j]));
    25         return res;
    26     }
    27 } A, F;
    28 inline Matrix kasumi(Matrix a, LL b){
    29     Matrix res;
    30     res.a[0][0] = res.a[1][1] = 1;
    31     while(b){
    32         if(b & 1) res = res * a;
    33         a = a * a;
    34         b >>= 1;
    35     }
    36     return res;
    37 }
    38 inline int kasumi(int a, int b){
    39     int res = 1;
    40     while(b){
    41         if(b & 1) res = mul(res, a);
    42         a = mul(a, a);
    43         b >>= 1;
    44     }
    45     return res;
    46 }
    47 inline int calc(int x){
    48     A.a[0][0] = x + 1;
    49     A.a[1][1] = 1;
    50     A.a[1][0] = A.a[0][1] = x;
    51     F = kasumi(A, n);
    52     return F.a[0][0];
    53 }
    54 int main(){
    55     scanf("%d", &t);
    56     while(t --){
    57         scanf("%lld%d%d", &n, &k, &p);
    58         fac.clear();
    59         int tmp = p - 1;
    60         for(Rint i = 2;i * i <= tmp;i ++)
    61             if(!(tmp % i)){
    62                 fac.push_back(i);
    63                 while(!(tmp % i)) tmp /= i;
    64             }
    65         if(tmp > 1) fac.push_back(tmp);
    66         for(g = 2;;g ++){
    67             bool flag = true;
    68             for(Rint i = 0;i < fac.size() && flag;i ++)
    69                 if(kasumi(g, (p - 1) / fac[i]) == 1) flag = false;
    70             if(flag) break;
    71         }
    72         g = kasumi(g, (p - 1) / k);
    73         int ans = 0;
    74         for(Rint i = 0, now = 1;i < k;i ++, now = mul(now, g))
    75             ans = add(ans, calc(now));
    76         ans = mul(ans, kasumi(k, p - 2));
    77         printf("%d\n", ans);
    78     }
    79 }
    View Code
  • 相关阅读:
    Spring AOP切点表达式用法总结
    各种文档地址记录
    回顾乐信集团工作经历
    Redux的简单使用
    简单介绍软件测试(一)
    jupyter notebook 安装代码提示功能
    解决matplotlib不显示中文的问题
    前端生成二维码并下载(PC端)
    XSS绕过常见方式
    JWT的安全问题
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/10502530.html
Copyright © 2011-2022 走看看