#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,a,n) for (ll i=a;i
#define per(i,a,n) for (ll i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((ll)(x).size())
typedef long long ll;
typedef vector<ll> VI;
typedef pair<ll, ll> PII;
const ll mod = 998244353;
ll powmod(ll a, ll b) {
ll res = 1;
a %= mod;
assert(b >= 0);
for (; b; b >>= 1) {
if (b & 1)
res = res*a%mod;
a = a*a%mod;
}
return res;
}
namespace linear_seq {
const ll N = 10010;
ll res[N], base[N], _c[N], _md[N];
vector<ll> Md;
void mul(ll *a, ll *b, ll k) {
rep(i, 0, k + k) _c[i] = 0;
rep(i, 0, k) if (a[i])
rep(j, 0, k) _c[i + j] = (_c[i + j] + a[i] * b[j]) % mod;
for (ll i = k + k - 1; i >= k; i--)
if (_c[i])
rep(j, 0, SZ(Md)) _c[i - k + Md[j]] = (_c[i - k + Md[j]] - _c[i] * _md[Md[j]]) % mod;
rep(i, 0, k) a[i] = _c[i];
}
ll solve(ll n,const VI &a,const VI &b) {
ll ans = 0, pnt = 0;
ll k = SZ(a);
assert(SZ(a) == SZ(b));
rep(i, 0, k) _md[k - 1 - i] = -a[i];
_md[k] = 1;
Md.clear();
rep(i, 0, k) if (_md[i] != 0)
Md.push_back(i);
rep(i, 0, k) res[i] = base[i] = 0;
res[0] = 1;
while ((1ll << pnt) <= n)
pnt++;
for (ll p = pnt; p >= 0; p--) {
mul(res, res, k);
if ((n >> p) & 1) {
for (ll i = k - 1; i >= 0; i--)
res[i + 1] = res[i];
res[0] = 0;
rep(j, 0, SZ(Md)) res[Md[j]] = (res[Md[j]] - res[k] * _md[Md[j]]) % mod;
}
}
rep(i, 0, k) ans = (ans + res[i] * b[i]) % mod;
if (ans < 0)
ans += mod;
return ans;
}
void BM(VI &s,VI &C) {
C.clear();
C.pb(1);
VI B(1, 1);
ll L = 0, m = 1, b = 1;
rep(n, 0, SZ(s)) {
ll d = 0;
rep(i, 0, L + 1) d = (d + (ll)C[i] * s[n - i]) % mod;
if (d == 0)
++m;
else if (2 * L <= n) {
VI T = C;
ll c = mod - d*powmod(b, mod - 2) % mod;
while (SZ(C) < SZ(B) + m)
C.pb(0);
rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c*B[i]) % mod;
L = n + 1 - L;
B = T;
b = d;
m = 1;
} else {
ll c = mod - d*powmod(b, mod - 2) % mod;
while (SZ(C) < SZ(B) + m)
C.pb(0);
rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c*B[i]) % mod;
++m;
}
}
}
ll gao(VI &a, ll n) {
VI c;
BM(a,c);
c.erase(c.begin());
rep(i, 0, SZ(c)) c[i] = (mod - c[i]) % mod;
rep(i,0,SZ(c)){
printf("%lld ",c[i]);
}
printf("\n");
return solve(n, c, VI(a.begin(), a.begin() + SZ(c)));
}
};
int main() {
ll n,m;
scanf("%lld%lld", &n,&m);m++;
VI vec;
for(int i=1;i<=n;i++){
ll j;
scanf("%lld",&j);
vec.push_back(j);
}
printf("%lld\n", linear_seq::gao(vec, m - 1));
}
Another
#include
#define rep(i,a,b) for(ll i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const ll N=25;
const ll mo=1e9+7;
ll fpow(ll a,ll b){
ll ans=1;
while(b>0){if(b&1)ans=ans*a%mo;b>>=1;a=a*a%mo;}
return ans;
}
vector<ll> BM(const vector<ll> &s){
vector<ll> C={1},B={1},T;
ll L=0,m=1,b=1;
rep(n,0,s.size()-1){
ll d=0;
rep(i,0,L)d=(d+s[n-i]%mo*C[i])%mo;
if(d==0)m++;
else{
T=C;
ll t=mo-fpow(b,mo-2)*d%mo;
while(C.size()<B.size()+m)C.push_back(0);
rep(i,0,B.size()-1)C[i+m]=(C[i+m]+t*B[i])%mo;
if(2*L>n)m++;
else L=n+1-L,B=T,b=d,m=1;
}
}
return C;
}
ll MatrixSolve(const vector<ll> &s,const vector<ll> &C,ll n){
if(n<s.size())return s[n];
ll k=C.size()-1,b=n-k+1;
static ll B[N][N],t[N],a[N],c[N][N];
rep(i,0,k-1)a[i]=s[i];
rep(i,0,k-1)rep(j,0,k-1)B[i][j]=j==0?((C[i+1]>0)*mo-C[i+1]):(i==j-1);
while(b){
if(b&1){
rep(i,0,k-1)t[i]=0;
rep(i,0,k-1)rep(j,0,k-1)t[i]=(t[i]+a[k-j-1]*B[j][k-i-1])%mo;
rep(i,0,k-1)a[i]=t[i];
}
b>>=1;
rep(i,0,k-1)rep(j,0,k-1)c[i][j]=0;
rep(r,0,k-1)rep(j,0,k-1)if(B[r][j])rep(i,0,k-1)c[i][j]=(c[i][j]+B[i][r]*B[r][j])%mo;
rep(i,0,k-1)rep(j,0,k-1)B[i][j]=c[i][j];
}
return a[k-1];
}
ll fastMatrixSolve(const vector<ll> &s,const vector<ll> &C,ll n){
if(n<s.size())return s[n];
ll k=C.size()-1,b=n-k+1;
static ll B[N][N][64],t[N],a[N],c[N][N],init_flag=1;
if(init_flag){
init_flag=0;
rep(i,0,k-1)rep(j,0,k-1)B[i][j][0]=j==0?((C[i+1]>0)*mo-C[i+1]):(i==j-1);
for(ll it=1;it<64;it++){
rep(i,0,k-1)rep(j,0,k-1)B[i][j][it]=0;
rep(r,0,k-1)rep(j,0,k-1)if(B[r][j][it-1])rep(i,0,k-1)B[i][j][it]=(B[i][j][it]+B[i][r][it-1]*B[r][j][it-1])%mo;
}
}
rep(i,0,k-1)a[i]=s[i];
ll it=0;
while(b){
if(b&1){
rep(i,0,k-1)t[i]=0;
rep(i,0,k-1)rep(j,0,k-1)t[i]=(t[i]+a[k-j-1]*B[j][k-i-1][it])%mo;
rep(i,0,k-1)a[i]=t[i];
}
b>>=1;
it++;
}
return a[k-1];
}
class NewtonPoly{
public:
ll f[N],d[N],x[N],n=0;
void add(ll X,ll Y){
x[n]=X,f[n]=Y%mo;
rep(i,1,n)f[n-i]=(f[n-i+1]-f[n-i])%mo*fpow((x[n]-x[n-i])%mo,mo-2)%mo;
d[n++]=f[0];
}
ll operator () (ll X)const{
ll ans=0,t=1;
rep(i,0,n-1)ans=(ans+d[i]*t)%mo,t=(X-x[i])%mo*t%mo;
return ans+mo*(ans<0);
}
};
bool polyCheck(const vector<ll> &C){
ll m=mo-C[1],last=1;
rep(i,1,C.size()-1){
last=last*(m-i+1)%mo*fpow(i,mo-2)%mo;
if(last!=(i&1?(mo-C[i]):C[i]))return false;
}
return true;
}
class intMatrix{
public:
ll a[N][N],n,m;
bool operator < (const intMatrix &b)const{
rep(i,0,n-1)rep(j,0,m-1)if(a[i][j]!=b.a[i][j])return a[i][j]<b.a[i][j];
return false;
}
bool operator == (const intMatrix &b)const{
return !(*this<b) && !(b<*this);
}
static intMatrix Eye(ll n){
intMatrix c;
c.n=c.m=n;
rep(i,0,n-1)rep(j,0,n-1)c.a[i][j]=i==j;
return c;
}
intMatrix operator * (const intMatrix &b)const{
assert(m==b.n);
intMatrix c;
c.n=n,c.m=b.m;
rep(i,0,c.n-1)rep(j,0,c.m-1)c.a[i][j]=0;
rep(i,0,c.n-1)rep(j,0,c.m-1)rep(k,0,m-1)c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mo;
return c;
}
intMatrix operator ^ (int t)const{
assert(n==m);
intMatrix c=Eye(n),b=*this;
while(t){if(t&1)c=c*b;b=b*b;t>>=1;}
return c;
}
void print()const{
rep(i,0,n-1)rep(j,0,m-1)cout<<a[i][j]<<" \n"[j==m-1];
cout<<endl;
}
};
ll periodSolve(const vector<ll> &C,ll d){
static map<intMatrix,ll> tab;
tab.clear();
ll k=C.size()-1;
assert(C[k]!=0);
intMatrix A,B,T=intMatrix::Eye(k),D=T;
A.n=A.m=B.n=B.m=k;
rep(i,0,k-1)rep(j,0,k-1)A.a[i][j]=j==0?((C[i+1]>0)*mo-C[i+1]):(i==j-1);
rep(i,0,k-1)rep(j,0,k-1)B.a[i][j]=j==k-1?((mo-C[i])*fpow(C[k],mo-2)%mo):(i==j+1);
rep(i,1,d){
T=T*B;
if(T==D)return i;
tab[T]=i;
}
intMatrix Ad=A^d;
ll x=0;
while(1){
if(tab.find(D)!=tab.end())return x*d+tab[D];
D=D*Ad;
x++;
}
return -1;
}
ll polySolve(const vector<ll> &s,const vector<ll> &C,ll n){
if(n<s.size())return s[n];
static ll g[N],f[N],d[N];
ll k=(ll)C.size()-1,w=1;
rep(i,0,k)f[i]=i==1,d[i]=i==k?1:C[k-i];
while((w<<1)<=n)w<<=1;
while(w>>=1){
rep(i,0,k+k-2)g[i]=0;
rep(i,0,k-1)if(f[i])rep(j,0,k-1)(g[i+j]+=f[i]*f[j])%=mo;
for(ll i=k+k-2;i>=k;i--)if(g[i])rep(j,1,k)(g[i-j]-=g[i]*d[k-j])%=mo;
rep(i,0,k-1)f[i]=g[i];
if(w&n)for(ll i=k;i>=0;i--)f[i]=i==k?f[i-1]:(i==0?-f[k]*d[i]:(f[i-1]-f[k]*d[i]))%mo;
}
ll ans=0;
rep(i,0,k-1)(ans+=f[i]*s[i])%=mo;
return ans+(ans<0)*mo;
}
class Sequence{
public:
ll poly;
vector<ll> A,C;
NewtonPoly P;
void build(const vector<ll> &s){
A=s;
C=BM(A);
poly=polyCheck(C);
if(poly)rep(i,0,s.size()-1)P.add(i,s[i]);
}
ll operator () (ll n)const{
return poly?P(n):polySolve(A,C,n);
}
friend ostream &operator << (ostream &o,const Sequence &b){
o<<"f(n)";
rep(i,1,b.C.size()-1)o<<"+("<<b.C[i]<<")*f(n-"<<i<<")";
o<<"=0 (mod "<<mo<<")";
return o;
}
ll period()const{
ll M=periodSolve(C,(ll)sqrt(mo)),ans=M;
return M;
for(ll i=1;i*i<=M;i++)if(M%i==0){
ll d=i,flag=1;
rep(i,0,(ll)C.size()-2)if((*this)(d+i)!=A[i])flag=0;
if(flag)ans=min(ans,d);
d=M/i,flag=1;
rep(i,0,(ll)C.size()-2)if((*this)(d+i)!=A[i])flag=0;
if(flag)ans=min(ans,d);
}
return ans;
}
}F;
int main(){
ios::sync_with_stdio(false);
F.build({1,1,2,3,5,8,13,21});
cout<<F<<endl;
F.build({0,1,4,9,16,25,36,49});
cout<<F<<endl;
F.build({0,1,5,15,35,70,126,210,330,495,715});
cout<<F<<endl;
F.build({0,1,2,0,1,2,0,1,2});
cout<<F<<endl;
F.build({0,1,1,2,4,7,13});
cout<<F<<endl;
return 0;
}