zoukankan      html  css  js  c++  java
  • loj 6485

    单位根反演好题

    题意:求$sum_{i=0}^{n}C_{n}^{i}S^{i}a_{ i mod 4 }$

    看到$i$ $mod$ $4$这种东西,很显然要分类讨论啦

    于是变成了这种形式:

    $sum_{d=0}^{3}a_{d}sum_{i=0}^{n}[$ $iequiv d$ $mod$ $4$]$C_{n}^{i}S^{i}$

    前面暂时先不管,如果不考虑到取模的限制,发现我们实际只是在求这个东西

    $sum_{i=0}^{n}C_{n}^{i}S^{i}$

    写成形式幂级数(生成函数)的形式,就是这样:

    $sum_{i=0}^{n}C_{n}^{i}S^{i}x^{i}$

    感觉有点像二项式定理,把原式改写成这个形式:

    $sum_{i=0}^{n}C_{n}^{n-i}S^{n-i}$

    再去构造生成函数,也就是:

    $sum_{i=0}^{n}C_{n}^{n-i}S^{n-i}x^{i}$

    这就是二项式定理了嘛

    也就是:

    $(x+S)^{n}=sum_{i=0}^{n}C_{n}^{n-i}S^{n-i}x^{i}$

    可是没有什么帮助吧...

    其实是有的!

    不要忘了单位根反演的表达式:

    若$f(x)=sum_{i=0}^{n}a_{i}x^{i}$,则$sum_{i=0}^{n}a_{i}[d|i]=frac{1}{d}sum_{p=0}^{d-1}f(w_{d}^{p})$

    那么我们看到,当模4等于0时,所求的部分即为$sum_{i=0}^{n}C_{n}^{n-i}S^{n-i}[4|i]$

    那么也就是$frac{1}{4}sum_{i=0}^{3}f(w_{4}^{i})$

    这样这一部分就...算完了

    可是$mod$ $4$不为0的部分怎么办呢?

    多项式平移啊!

    我们整体乘一个$x$,这样现在模$4$为0的项就是原来模$4$为1的项了嘛(不要忘了我们已经反转了系数!)

    这样就可做了

    最后的表达式即为$frac{1}{4}sum_{d=0}^{3}a_{(n+d)mod 4}sum_{p=0}^{3}(w_{4}^{p})^{d}f(w_{4}^{p})$

    最后也就是$frac{1}{4}sum_{d=0}^{3}a_{(n+d)mod 4}sum_{p=0}^{3}(w_{4}^{p})^{d}(w_{4}^{p}+S)^{n}$

    代码也就很好写了

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #define ll long long
    using namespace std;
    const ll mode=998244353;
    ll f[4];
    ll w[4];
    ll a[4];
    int T;
    ll n,S;
    ll pow_mul(ll x,ll y)
    {
        ll ret=1;
        while(y)
        {
            if(y&1)ret=ret*x%mode;
            x=x*x%mode,y>>=1;
        }
        return ret;
    }
    int main()
    {
        w[0]=1;
        for(int i=1;i<=3;i++)w[i]=w[i-1]*pow_mul(3,(mode-1)/4)%mode;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld",&n,&S);
            for(int i=0;i<=3;i++)scanf("%lld",&a[i]);
            for(int i=0;i<=3;i++)f[i]=pow_mul(w[i]+S,n);
            ll ans=0;
            for(int i=0;i<=3;i++)
            {
                ll s=0;
                for(int j=0;j<=3;j++)s+=f[j],s%=mode;
                for(int j=0;j<=3;j++)f[j]=f[j]*w[j]%mode;
                s=s*a[(n+i)%4]%mode;
                ans=(ans+s)%mode;
            }
            printf("%lld
    ",ans*pow_mul(4,mode-2)%mode);
        }
        return 0;
    }
  • 相关阅读:
    [HDU1561]The more, The Better
    [洛谷P1352][codevs1380]没有上司的舞会
    【51Nod1773】A国的贸易 解题报告
    快速沃尔什变换
    【SDOI2015】序列统计 解题报告
    【CF438E】小朋友和二叉树 解题报告
    多项式Ⅰ
    洛谷 P5105 不强制在线的动态快速排序
    【BZOJ4916】神犇和蒟蒻 解题报告
    【BZOJ3309】DZY Loves Math 解题报告
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11059946.html
Copyright © 2011-2022 走看看