请求开大时限
查看原帖
请求开大时限
886055
MoonCake2011楼主2024/8/14 15:35

首先 【模板】多项式指数函数(多项式 exp) 的时限为 2s。

而这题 1s,对于我与几位大常熟选手不太友好。

或者有谁帮我卡卡常或者证明时复假掉了。

代码。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Pmod 998244353ll
#define Gmod 3ll
#define Gimod 332748118ll
const int y=((__int128)1<<64)/Pmod;
int n,m;
vector<int>a,b,c,d;
inline int PMOD(int a){
	__int128 Q=((__int128)(a)*y)>>64;
	return a-Q*Pmod;
}
inline int power(int x,int y){
	if(y==0) return 1;
	int tot=power(x,y>>1);
	if(y&1) return PMOD(PMOD(tot*tot)*x);
	else return PMOD(tot*tot);
}
void NTT(vector<int>&a,int val){
	int n=a.size()-1,mid=(a.size()>>1)-1;
	if(n==0) return;
	vector<int>p,q;
	for(int i=0;i<=mid;i++) p.push_back(0),q.push_back(0);
	for(int i=0;i<=n;i+=2) p[i>>1]=a[i],q[i>>1]=a[i+1];
	NTT(p,val),NTT(q,val);
	int Wn=power(((val==1) ? Gmod : Gimod),(Pmod-1)/a.size()),w=1;
	for(int i=0;i<=mid;i++,w=PMOD(w*Wn)){
	    int t=PMOD(w*q[i]);
	    a[i]=PMOD(p[i]+t),a[i+mid+1]=PMOD(p[i]-t+Pmod);
	}
}
void INV(vector<int>a,vector<int>&b,int M){
	if(M==1){
		b.clear();
		b.push_back(power(a[0],Pmod-2));
		return;
	}
	INV(a,b,M+1>>1);
	int len=1;while(len<M*2) len*=2;
	len--;
	while(a.size()<=len) a.push_back(0);
	while(a.size()>len+1) a.pop_back();
	while(b.size()<a.size()) b.push_back(0);
	for(int i=M;i<=len;i++) a[i]=0;
	NTT(a,1),NTT(b,1);
	for(int i=0;i<=len;i++) b[i]=(2-a[i]*b[i]%Pmod+Pmod)%Pmod*b[i]%Pmod;
	NTT(b,-1);
	int inv=power(len+1,Pmod-2);
	for(int i=0;i<=len;i++) b[i]=(b[i]*inv)%Pmod;
	for(int i=M;i<=len;i++) b[i]=0;
}
inline void get_cut(vector<int>a,vector<int>&b){
	b.clear();
	for(int i=1;i<a.size();i++) b.push_back(i*a[i]%Pmod);
	b.push_back(0);
}
inline void get_int(vector<int>a,vector<int>&b){
	b.clear();
	b.push_back(0);
	for(int i=1;i<a.size();i++) b.push_back(a[i-1]*power(i,Pmod-2)%Pmod);
}
inline void getln(vector<int>&a,int n){
	get_cut(a,b);
	INV(a,c,n+1);
	int len=1;while(len<=2*n) len*=2;
	len--;
	while(b.size()<=len) b.push_back(0);
	while(b.size()>len+1) b.pop_back();
	while(c.size()<=len) c.push_back(0);
	while(c.size()>len+1) c.pop_back();
	NTT(b,1),NTT(c,1);
	for(int i=0;i<b.size();i++) b[i]=(b[i]*c[i])%Pmod;
	NTT(b,-1);
	int inv=power(len+1,Pmod-2);
	for(int i=0;i<b.size();i++) b[i]=(b[i]*inv)%Pmod;
	get_int(b,a);
}
void getexp(vector<int>a,vector<int>&b,int n){
	if(n==1){
		b.clear();
		b.push_back(1);
		return;
	}
	getexp(a,b,(n+1)>>1);
	vector<int>p=b;
	getln(p,n);
	int len=1;while(len<=n*2) len*=2;
	len--;
	while(a.size()<=len) a.push_back(0);
	while(a.size()>len+1) a.pop_back();
	while(b.size()<=len) b.push_back(0);
	while(b.size()>len+1) b.pop_back();
	while(p.size()<=len) p.push_back(0);
	while(p.size()>len+1) p.pop_back();
	p[0]=(a[0]-p[0]+1+Pmod)%Pmod;
	for(int i=1;i<=len;i++) p[i]=(a[i]-p[i]+Pmod)%Pmod;
	for(int i=n;i<=len;i++) b[i]=p[i]=0;
	NTT(b,1),NTT(p,1);
	for(int i=0;i<=len;i++) b[i]=(b[i]*p[i])%Pmod;
	NTT(b,-1);
	int inv=power(len+1,Pmod-2);
	for(int i=0;i<=len;i++) b[i]=(b[i]*inv)%Pmod;
	for(int i=n;i<=len;i++) b[i]=p[i]=0;
}
int V[100010];
int buc[100010];
int Inv[100010];
signed main() {
//	freopen("data.txt","r",stdin);
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>V[i],buc[V[i]]++;
	for(int i=0;i<=m;i++) a.push_back(0),Inv[i]=power(i,Pmod-2);
	for(int i=1;i<=m;i++) if(buc[i]) for(int j=1;i*j<=m;j++) a[i*j]=(a[i*j]+buc[i]*Inv[j]%Pmod)%Pmod;
	getexp(a,d,m+1);
	for(int i=1;i<=m;i++) cout<<d[i]<<"\n";
	return 0;
}
2024/8/14 15:35
加载中...