萌新调了一晚上了/kk
MTT 部分(66~135 行)是直接粘的我的板子,AC 记录。
悬三个关注/kk
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<unordered_map>
#include<vector>
#include<queue>
#include<bitset>
#include<set>
#include<ctime>
#include<random>
#include<cassert>
#define x1 xx1
#define y1 yy1
#define IOS ios::sync_with_stdio(false)
#define ITIE cin.tie(0);
#define OTIE cout.tie(0);
#define PY puts("Yes")
#define PN puts("No")
#define PW puts("-1")
#define P0 puts("0")
#define P__ puts("")
#define PU puts("--------------------")
#define popc __builtin_popcount
#define mp make_pair
#define fi first
#define se second
#define gc getchar
#define pc putchar
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rep(a,b,c) for(int a=(b);a<=(c);++a)
#define per(a,b,c) for(int a=(b);a>=(c);--a)
#define reprange(a,b,c,d) for(int a=(b);a<=(c);a+=(d))
#define perrange(a,b,c,d) for(int a=(b);a>=(c);a-=(d))
#define graph(i,j,k,l) for(int i=k[j];i;i=l[i].nxt)
#define lowbit(x) (x&-x)
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define mem(x,y) memset(x,y,sizeof x)
//#define double long double
//#define int long long
//#define int __int128
using namespace std;
typedef long long i64;
using pii=pair<int,int>;
bool greating(int x,int y){return x>y;}
bool greatingll(long long x,long long y){return x>y;}
inline int rd(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}return x*f;
}
inline void write(int x,char ch='\0'){
if(x<0){x=-x;putchar('-');}
int y=0;char z[40];
while(x||!y){z[y++]=x%10+48;x/=10;}
while(y--)putchar(z[y]);if(ch!='\0')putchar(ch);
}
bool Mbg;
const int maxn=2.7e5+5,maxm=4e5+5,inf=0x3f3f3f3f;
const long long llinf=0x3f3f3f3f3f3f3f3f;
const int mod0=469762049,mod1=998244353,mod2=1004535809,mod=1e9+7;
const i64 mod01=1ll*mod0*mod1;
const int g=3,gn0=156587350,gn1=332748118,gn2=334845270;
int n,k,a[maxn],r[maxn];
inline int ksm(int x,int y,int p){
int res=1;
for(;y;y>>=1,x=1ll*x*x%p)if(y&1)res=1ll*res*x%p;
return res;
}
struct Int{
int a,b,c;
inline Int(int _a=0,int _b=0,int _c=0){a=_a,b=_b,c=_c;}
inline int transfer(){
int inv0=ksm(mod0,mod1-2,mod1);
int x=1ll*((b-a+mod1)%mod1)*inv0%mod1;
i64 d=(1ll*x*mod0%mod01+a)%mod01;
int inv01=ksm(mod01%mod2,mod2-2,mod2);
int y=1ll*((c-d%mod2+mod2)%mod2)*inv01%mod2;
return (1ll*(mod01%mod)*(y%mod)%mod+d%mod)%mod;
}
};
inline Int operator+(Int x,Int y){return Int((x.a+y.a)%mod0,(x.b+y.b)%mod1,(x.c+y.c)%mod2);}
inline Int operator-(Int x,Int y){return Int((x.a+mod0-y.a)%mod0,(x.b+mod1-y.b)%mod1,(x.c+mod2-y.c)%mod2);}
inline Int operator*(Int x,Int y){return Int((1ll*x.a*y.a)%mod0,(1ll*x.b*y.b)%mod1,(1ll*x.c*y.c)%mod2);}
Int _wn[2][maxn];
void Poly_init(int lim=262144){
for(int mid=1;mid<lim;mid<<=1){
_wn[1][mid]=Int(ksm(g,(mod0-1)/(mid<<1),mod0),ksm(g,(mod1-1)/(mid<<1),mod1),ksm(g,(mod2-1)/(mid<<1),mod2));
_wn[0][mid]=Int(ksm(gn0,(mod0-1)/(mid<<1),mod0),ksm(gn1,(mod1-1)/(mid<<1),mod1),ksm(gn2,(mod2-1)/(mid<<1),mod2));
}
}
struct Poly{
int lim,len;
vector<Int>arr;
Poly(){lim=len=0;arr.clear();}
void ntt(int t){
rep(i,0,lim-1)if(i<r[i])swap(arr[i],arr[r[i]]);
for(int mid=1;mid<lim;mid<<=1){
const Int wn=_wn[t][mid];
reprange(i,0,lim-1,mid<<1){
Int w=Int(1,1,1);
for(int j=i;j<i+mid;++j,w=w*wn){
Int x=arr[j],y=arr[j+mid]*w;
arr[j]=x+y,arr[j+mid]=x-y;
}
}
}
if(!t){
Int invlim=Int(ksm(lim,mod0-2,mod0),ksm(lim,mod1-2,mod1),ksm(lim,mod2-2,mod2));
rep(i,0,lim-1)arr[i]=arr[i]*invlim;
}
}
};
Poly operator*(Poly x,Poly y){
int lim=1,wei=0;
while(lim<=x.len+y.len)lim<<=1,++wei;
x.lim=y.lim=lim;
rep(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<(wei-1));
vector<Int>xrr(lim),yrr(lim);
// assert((int)x.arr.size()>=x.len&&(int)y.arr.size()>=y.len);
rep(i,0,x.len)xrr[i]=x.arr[i];
rep(i,0,y.len)yrr[i]=y.arr[i];
// rep(i,0,lim-1)write(xrr[i].a,32),write(xrr[i].b,32),write(xrr[i].c,10);PU;
x.arr=xrr,y.arr=yrr;
x.ntt(1),y.ntt(1);
rep(i,0,lim-1)x.arr[i]=x.arr[i]*y.arr[i];
x.ntt(0);
x.len+=y.len;
return x;
}
Poly solve(int l,int r){
if(l==r){
Poly F;
F.len=1,F.arr.resize(2);
F.arr[0]=Int(1,1,1),F.arr[1]=Int(a[l],a[l],a[l]);
return F;
}
int mid=l+r>>1;
return solve(l,mid)*solve(mid+1,r);
}
inline void solve_the_problem(){
n=rd(),k=rd();
rep(i,1,n)a[i]=rd();
Poly_init();
Poly res=solve(1,n);
write(res.arr[k].transfer());
}
bool Med;
signed main(){
// freopen(".in","r",stdin);freopen(".out","w",stdout);
// fprintf(stderr,"%.3lfMB\n",(&Mbg-&Med)/1048576.0);
int _=1;
while(_--)solve_the_problem();
}
/*
10 5
4783 4238 9875 9543 1423 2134783 238419 129384 361472 83672
output:395365112
*/