[hdu7023]Yet Another Matrix Problem

关于$f(x)$的条件,将$C=A\times 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}=\begin{cases}2(m+1)^{n}-1&(x=0)\\\sum_{d\mid x}{d+n-1\choose n-1}{\frac{x}{d}+n-1\choose n-1}&(x\ge 1)\end{cases}$​​​

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

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

最终,总复杂度为$o(m\log 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\n",v[i]);
128     }
129     return 0;
130 } 
View Code

 

posted @ 2021-08-30 12:17  PYWBKTDA  阅读(63)  评论(0编辑  收藏  举报