• [hdu7023]Yet Another Matrix Problem


    关于$f(x)$的条件,将$C=A imes B$代入,即$sum_{i=1}^{n}sum_{j=1}^{n}sum_{k=1}^{r}A_{i,k}B_{k,j}=x$

    调换枚举顺序,即$sum_{k=1}^{r}(sum_{i=1}^{n}A_{i,k})(sum_{j=1}^{n}B_{k,j})=x$

    显然每一部分的值都是独立的,因此令$G_{x}$​​为$(sum_{i=1}^{n}A_{i,k})(sum_{j=1}^{n}B_{k,j})=x$​​的方案数,枚举其中一项的值并对$x$​​是否为0分类讨论,那么不难得到有$G_{x}=egin{cases}2(m+1)^{n}-1&(x=0)\sum_{dmid x}{d+n-1choose n-1}{frac{x}{d}+n-1choose n-1}&(xge 1)end{cases}$​​​

    令$G_{x}$对应的生成函数为$G(t)=sum_{xge 0}G_{x}t^{x}$,那么答案即为$[t^{x}]G^{r}(t)$(指$G^{r}(t)$的$x$​​次项系数),

    根据调和级数,可以$o(mlog m)$​​求出$G_{x}$​​​,$G^{r}(t)$利用多项式求幂也可以做到$o(mlog m)$​​

    最终,总复杂度为$o(mlog m)$​,可以通过

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 200005
      4 #define L 18
      5 #define mod 998244353
      6 #define ll long long
      7 #define vi vector<int>
      8 #define Add(x,y) (x+y<mod ? x+y : x+y-mod)
      9 #define Sub(x,y) (x>=y ? x-y : x-y+mod)
     10 int t,n,m,fac[N],inv[N];
     11 vi v;
     12 int C(int n,int m){
     13     return (ll)fac[n]*inv[m]%mod*inv[n-m]%mod;
     14 }
     15 int qpow(int n,int m,int Mod=mod){
     16     int s=n,ans=1;
     17     while (m){
     18         if (m&1)ans=(ll)ans*s%Mod;
     19         s=(ll)s*s%Mod;
     20         m>>=1;
     21     }
     22     return ans;
     23 }
     24 namespace Poly{
     25     int inv[1<<L],rev[1<<L],S[2][L][1<<L];
     26     void init(){
     27         inv[0]=inv[1]=1;
     28         for(int i=2;i<(1<<L);i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
     29         for(int i=0;i<L;i++){
     30             int s=qpow(3,(mod-1>>i+1)),ss=qpow(s,mod-2);
     31             S[0][i][0]=S[1][i][0]=1;
     32             for(int j=1;j<(1<<i);j++){
     33                 S[0][i][j]=(ll)s*S[0][i][j-1]%mod;
     34                 S[1][i][j]=(ll)ss*S[1][i][j-1]%mod;
     35             }
     36         }
     37     }
     38     vi Get(int num){
     39         vi ans;
     40         ans.push_back(num);
     41         return ans;
     42     }
     43     vi add(vi a,vi b,int n){
     44         a.resize(n);
     45         for(int i=0;(i<n)&&(i<b.size());i++)a[i]=Add(a[i],b[i]);
     46         return a;
     47     }
     48     vi sub(vi a,vi b,int n){
     49         a.resize(n);
     50         for(int i=0;(i<n)&&(i<b.size());i++)a[i]=Sub(a[i],b[i]);
     51         return a;
     52     }
     53     vi mul(vi a,int x,int n){
     54         a.resize(n);
     55         for(int i=0;(i<n)&&(i<a.size());i++)a[i]=(ll)x*a[i]%mod;
     56         return a;
     57     }
     58     vi Int(vi a,int n){
     59         a.resize(n);
     60         for(int i=n-1;i;i--)a[i]=(ll)inv[i]*a[i-1]%mod;
     61         a[0]=0;
     62         return a;
     63     }
     64     vi derive(vi a,int n){
     65         a.resize(n);
     66         for(int i=1;i<n;i++)a[i-1]=(ll)i*a[i]%mod;
     67         a[n-1]=0;
     68         return a;
     69     }
     70     void ntt(vi &a,int n,int p){
     71         for(int i=0;i<n;i++)
     72             if (i<rev[i])swap(a[i],a[rev[i]]);
     73         for(int i=2,ii=0;i<=n;i<<=1,ii++)
     74             for(int j=0;j<n;j+=i)
     75                 for(int k=0;k<(i>>1);k++){
     76                     int x=a[j+k],y=(ll)S[p][ii][k]*a[j+k+(i>>1)]%mod;
     77                     a[j+k]=Add(x,y),a[j+k+(i>>1)]=Sub(x,y);
     78                 }
     79         if (p)a=mul(a,qpow(n,mod-2),n);
     80     }
     81     vi mul(vi a,vi b,int n){
     82         int m=0;
     83         while ((1<<m)<min(n,(int)a.size())+min(n,(int)b.size()))m++;
     84         m=(1<<m),a.resize(m),b.resize(m);
     85         for(int i=n;i<m;i++)a[i]=b[i]=0;
     86         for(int i=0;i<m;i++)rev[i]=(rev[i>>1]>>1)+(i&1)*(m>>1);
     87         ntt(a,m,0),ntt(b,m,0);
     88         for(int i=0;i<m;i++)a[i]=(ll)a[i]*b[i]%mod;
     89         ntt(a,m,1);
     90         while (a.size()>n)a.pop_back();
     91         return a;
     92     }
     93     vi Inv(vi a,int n){
     94         if (n==1)return Get(qpow(a[0],mod-2));
     95         vi ans=Inv(a,n+1>>1);
     96         return sub(mul(ans,2,n),mul(a,mul(ans,ans,n),n),n);
     97     }
     98     vi ln(vi a,int n){
     99         return Int(mul(derive(a,n),Inv(a,n),n),n);
    100     }
    101     vi exp(vi a,int n){
    102         if (n==1)return Get(1);
    103         vi ans=exp(a,n+1>>1);
    104         return mul(ans,sub(add(a,Get(1),n),ln(ans,n),n),n);
    105     }
    106     vi Qpow(vi a,int n,int m,int mm){
    107         int s=a[0];
    108         assert(s);
    109         a=mul(a,qpow(s,mod-2),n);
    110         return mul(exp(mul(ln(a,n),m,n),n),qpow(s,mm),n);
    111     }
    112 } 
    113 int main(){
    114     fac[0]=inv[0]=inv[1]=1;
    115     for(int i=1;i<N;i++)fac[i]=(ll)fac[i-1]*i%mod;
    116     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    117     for(int i=1;i<N;i++)inv[i]=(ll)inv[i-1]*inv[i]%mod;
    118     Poly::init();
    119     scanf("%d",&t);
    120     while (t--){
    121         scanf("%d%d",&n,&m);
    122         v.clear(),v.resize(++m);
    123         v[0]=(2*qpow(m,n)-1)%mod;
    124         for(int i=1;i<m;i++)
    125             for(int j=i;j<m;j+=i)v[j]=(v[j]+(ll)C(i+n-1,n-1)*C(j/i+n-1,n-1))%mod;
    126         v=Poly::Qpow(v,m,qpow(n,m-1),qpow(n,m-1,mod-1));
    127         for(int i=0;i<m;i++)printf("%d
    ",v[i]);
    128     }
    129     return 0;
    130 } 
    View Code
  • 相关阅读:
    [转载]Oracle Golden Gate
    git操作命令
    logger.error完整打印错误堆栈信息
    短网址算法
    YYYY-mm-dd HH:MM:SS大小写解释
    quarz时间配置
    Freemarket语法
    Java NIO:IO与NIO的区别
    idea常用到的命令
    linux 常用命令
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15205371.html
Copyright © 2020-2023  润新知