結果
| 問題 | No.3414 Aperiodic Sequence |
| コンテスト | |
| ユーザー |
tau1235
|
| 提出日時 | 2025-12-21 18:02:12 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 1,754 ms / 3,000 ms |
| コード長 | 6,424 bytes |
| 記録 | |
| コンパイル時間 | 4,525 ms |
| コンパイル使用メモリ | 310,672 KB |
| 実行使用メモリ | 23,592 KB |
| 最終ジャッジ日時 | 2025-12-21 18:02:32 |
| 合計ジャッジ時間 | 18,151 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#include<atcoder/modint>
using mint=atcoder::modint998244353;
struct FPS:vector<mint>{
using vector<mint>::vector;
static constexpr ll mod=998244353;
static FPS NTT(FPS &a,bool inverse=false){
const mint pr=3;
int n=a.size();
int log=0;
while (n>1<<log) log++;
FPS ret(n);
for (int i=0;i<n;i++){
int rev=0;
for (int k=0;k<log;k++) rev|=((i>>k)&1)<<(log-k-1);
ret[rev]=a[i];
}
for (int k=1;k<=log;k++){
int len=1<<k;
mint zeta=pr.pow((mod-1)>>k);
if (inverse) zeta=zeta.inv();
mint x=1;
for (int i=0;i<len/2;i++){
for (int j=i;j<n;j+=len){
mint r1=ret[j],r2=x*ret[j+len/2];
ret[j]=r1+r2;
ret[j+len/2]=r1-r2;
}
x*=zeta;
}
}
if (inverse){
mint ninv=mint(n).inv();
for (int i=0;i<n;i++) ret[i]*=ninv;
}
return ret;
}
static FPS convolution(FPS a,FPS b){
int na=a.size(),nb=b.size();
int nc=na+nb-1;
int n=1;
while (n<nc) n<<=1;
while ((int)a.size()<n) a.push_back(0);
while ((int)b.size()<n) b.push_back(0);
a=NTT(a);b=NTT(b);
for (int i=0;i<n;i++) a[i]*=b[i];
a=NTT(a,true);
a.resize(nc);
return a;
}
void shrink(){while((*this).size()&&(*this).back()==0)(*this).pop_back();}
FPS rev()const{
FPS ret(*this);
reverse(ret.begin(),ret.end());
return ret;
}
FPS pre(int sz)const{
FPS ret(min((int)(*this).size(),sz));
for (int i=0;i<min((int)(*this).size(),sz);i++) ret[i]=(*this)[i];
if ((int)ret.size()<sz) ret.resize(sz);
return ret;
}
FPS operator+=(const FPS &r){
if ((*this).empty()) (*this).resize(1);
for (int i=0;i<(int)r.size();i++) (*this)[i]+=r[i];
return *this;
}
FPS operator+=(const mint &r){
if ((*this).empty()) (*this).resize(1);
(*this)[0]+=r;
return *this;
}
FPS operator-=(const FPS &r){
if ((*this).empty()) (*this).resize(1);
for (int i=0;i<(int)r.size();i++) (*this)[i]-=r[i];
return *this;
}
FPS operator-=(const mint &r){
if ((*this).empty()) (*this).resize(1);
(*this)[0]-=r;
return *this;
}
FPS operator*=(const FPS &r){
if ((*this).empty()||r.empty()){
(*this).clear();
return *this;
}
return *this=convolution(*this,r);
}
FPS operator*=(const mint &r){
for (int i=0;i<(int)(*this).size();i++) (*this)[i]*=r;
return *this;
}
FPS operator/=(const FPS &r){
if ((*this).size()<r.size()){
(*this).clear();
return *this;
}
int n=(*this).size()-r.size()+1;
return *this=((*this).rev().pre(n)*r.rev().inv(n)).pre(n).rev();
}
FPS operator%=(const FPS &r){
*this-=*this/r*r;
shrink();
return *this;
}
FPS operator+(const FPS &r)const{return FPS(*this)+=r;}
FPS operator+(const mint &r)const{return FPS(*this)+=r;}
FPS operator-(const FPS &r)const{return FPS(*this)-=r;}
FPS operator-(const mint &r)const{return FPS(*this)-=r;}
FPS operator*(const FPS &r)const{return FPS(*this)*=r;}
FPS operator*(const mint &r)const{return FPS(*this)*=r;}
FPS operator/(const FPS &r)const{return FPS(*this)/=r;}
FPS operator%(const FPS &r)const{return FPS(*this)%=r;}
FPS inv(int deg=-1)const{
assert((*this)[0]!=mint(0));
if (deg==-1) deg=(*this).size();
FPS ret(deg);
ret[0]=(*this)[0].inv();
for (int d=1;d<deg;d<<=1){
FPS f(2*d),g(2*d);
for (int i=0;i<min((int)(*this).size(),2*d);i++) f[i]=(*this)[i];
for (int i=0;i<d;i++) g[i]=ret[i];
f=NTT(f);g=NTT(g);
for (int i=0;i<2*d;i++) f[i]*=g[i];
f=NTT(f,true);
for (int i=0;i<d;i++) f[i]=0;
f=NTT(f);
for (int i=0;i<2*d;i++) f[i]*=g[i];
f=NTT(f,true);
for (int i=d;i<min(2*d,deg);i++) ret[i]=-f[i];
}
return ret.pre(deg);
}
FPS diff()const{
int n=(*this).size();
FPS ret(max(0,n-1));
for (int i=1;i<n;i++) ret[i-1]=(*this)[i]*i;
return ret;
}
FPS integral()const{
int n=(*this).size();
FPS ret(n+1);
ret[0]=0;
for (int i=1;i<=n;i++) ret[i]=(*this)[i-1]/i;
return ret;
}
FPS log(int deg=-1)const{
assert((*this)[0]==1);
if (deg==-1) deg=(*this).size();
return ((*this).diff()*(*this).inv(deg)).pre(deg-1).integral();
}
FPS exp(int deg=-1)const{
assert((*this)[0]==0);
int n=(*this).size();
if (deg==-1) deg=n;
FPS ret(1);
ret[0]=1;
for (int d=1;d<deg;d<<=1) ret=(ret*(pre(d*2)-ret.log(d*2)+1)).pre(d*2);
return ret.pre(deg);
}
FPS pow(ll k,int deg=-1)const{
int n=(*this).size();
if (deg==-1) deg=n;
FPS ret(n);
ll shift=-1;
mint a=1,ainv=1;
for (int i=0;i<n;i++){
if ((*this)[i].val()){
shift=i;
a=(*this)[i];
ainv=a.inv();
break;
}
}
if (shift==-1){
if (k==0) ret[0]=1;
return ret.pre(deg);
}
if (__int128_t(shift)*k>=deg) return FPS(deg);
for (int i=shift;i<n;i++) ret[i-shift]=(*this)[i]*ainv;
ret=(ret.log()*k).exp();
a=a.pow(k);
shift*=k;
for (int i=n-1;i>=shift;i--) ret[i]=ret[i-shift]*a;
for (int i=0;i<shift;i++) ret[i]=0;
return ret.pre(deg);
}
};
using fps=FPS;
int main(){
int n,m;
cin>>n>>m;
vector<int> v(n);
for (int i=0;i<n;i++) cin>>v[i];
auto func=[&](vector<int> a){
int n=a.size();
queue<pair<fps,fps>> q;
for (int i=0;i<n;i++) q.push({{1},{1,-a[i]}});
while (q.size()>1){
auto f=q.front();q.pop();
auto g=q.front();q.pop();
fps h1=f.first*g.second+f.second*g.first,h2=f.second*g.second;
q.push({h1,h2});
}
auto [f,g]=q.front();
return (f*g.inv(m+1)).pre(m+1);
};
auto g=func(v);
vector<fps> f(m+1);
for (int i=1;i<=m;i++){
f[i]=fps(m/i+1);
mint s=g[i];
for (int j=1;j<=m/i;j++){
f[i][j]=s;
s*=g[i];
}
}
vector<vector<int>> d(m+1);
for (int i=2;i<=m;i++) for (int j=i;j<=m;j+=i) d[j].push_back(i);
vector<int> len(m+1,0);
auto rec=[&](auto rec,int x,ll pw)-> void {
assert(pw<=m);
if (len[pw]>=x) return;
if (x==1){
len[pw]=1;
return;
}
for (int i=2;pw*i<=m;i++) rec(rec,x/i,pw*i);
for (int i=len[pw]+1;i<=x;i++){
for (int j:d[i]){
f[pw][i]-=f[pw*j][i/j];
}
}
len[pw]=x;
return;
};
rec(rec,m,1);
for (int i=1;i<=m;i++) cout<<f[1][i].val()<<" \n"[i==m];
}
tau1235