80分求助
查看原帖
80分求助
367387
cainiaoshanglu楼主2022/2/3 19:51

蒟蒻求助,#4 和 #5 TLE了

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

void read(int &x){
	x=0;
	char c=getchar();
	while(!('0'<=c && c<='9')){
		c=getchar();
	}
	while('0'<=c && c<='9'){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
}
void write(int k){
    if(k>9){
        write(k/10);
    }
    putchar('0'+k%10);
}
const int md=998244353,g=3,rg=332748118;
int powr(int b,int k){
	int res=1;
	for(;k;b=(1ll*b*b)%md,k>>=1){
		if(k%2){
			res=(1ll*res*b)%md;
		}
	}
	return res;
}
int mod(int k){
	if(k>=md){
		return k-md;
	}else{
		return k;
	}
}
int flp[2100010],inv[100010];
inline void flip(int siz){
	for(int i=0;i<siz;i++){
		flp[i]=flp[i>>1]>>1;
		if(i&1){
			flp[i]|=siz>>1;
		}
	}
}
struct Poly{
	vector<int> val;
	Poly(){}
	Poly(const vector<int>& v){
		val=v;
	}
	Poly(int* v,int siz){
		for(int i=0;i<siz;i++){
			val.push_back(v[i]);
		}
	}
	Poly(int k){
		val.push_back(1);
	}
	void show(){
		for(int i=0;i<val.size();i++){
			printf("%d ",val[i]);
		}
	}
	int size(){
		return val.size();
	}
	int& operator[](int k){
		while(val.size()<=k){
			val.push_back(0);
		}
		return val[k];
	}
	friend Poly operator+(Poly a,Poly b){
		Poly res;
		if(a.size()<b.size()){
			swap(a,b);
		}
		for(int i=0;i<a.size();i++){
			res[i]=(a[i]+b[i])%md;
		}
		return res;
	}
	friend Poly operator-(Poly a,Poly b){
		Poly res;
		for(int i=0;i<max(a.size(),b.size());i++){
			res[i]=mod(a[i]-b[i]+md);
		}
		return res;
	}
	friend Poly operator*(Poly a,int b){
		for(int i=0;i<a.size();i++){
			a[i]=(1ll*a[i]*b)%md;
		}
		return a;
	}
	friend Poly operator*(int b,Poly a){
		return a*b;
	}
	vector<int> NTT(){
		int siz=val.size();
		vector<int> res=val;
		for(int i=0;i<siz;i++){
			if(i<flp[i]){
				swap(res[i],res[flp[i]]);
			}
		}
		for(int i=1;i<siz;i<<=1){
			int rt=powr(g,(md-1)/(i<<1));
			for(int j=0;j<siz;j+=(i<<1)){
				int cur=1;
				for(int k=0;k<i;k++){
					cur=(1ll*cur*rt)%md;
					int x=res[j+k],y=1ll*cur*res[i+j+k]%md;
					res[j+k]=mod(x+y);
					res[i+j+k]=mod(x-y+md);
				}
			}
		}
		return res;
	}
};
Poly INTT(const vector<int> &val){
	int siz=val.size();
	Poly res(val);
	for(int i=0;i<siz;i++){
		if(i<flp[i]){
			swap(res[i],res[flp[i]]);
		}
	}
	for(int i=1;i<siz;i<<=1){
		int rt=powr(rg,(md-1)/(i<<1));
		for(int j=0;j<siz;j+=(i<<1)){
			int cur=1;
			for(int k=0;k<i;k++){
				cur=(1ll*cur*rt)%md;
				int x=res[j+k],y=1ll*cur*res[i+j+k]%md;
				res[j+k]=mod(x+y);
				res[i+j+k]=mod(x-y+md);
			}
		}
	}
	return Poly(res);
}
Poly operator*(Poly a,Poly b){
	int tt=a.size()+b.size()-1,siz=1;
	while(siz<tt){
		siz<<=1;
	}
	a[siz-1];
	b[siz-1];
	flip(siz);
	vector<int> an=a.NTT(),bn=b.NTT(),res(siz,0);
	swap(an[0],an[siz-1]);
	for(int i=siz-1;i>1;i--){
		swap(an[i],an[i-1]);
	}
	swap(bn[0],bn[siz-1]);
	for(int i=siz-1;i>1;i--){
		swap(bn[i],bn[i-1]);
	}
	for(int i=0;i<siz;i++){
		res[i]=1ll*an[i]*bn[i]%md;
		//printf("%lld ",res[i]);
	}
	Poly k=INTT(res);
	swap(k[0],k[siz-1]);
	for(int i=siz-1;i>1;i--){
		swap(k[i],k[i-1]);
	}
	int inv=powr(siz,md-2);
	for(int i=0;i<siz;i++){
		k[i]=(1ll*k[i]*inv)%md;
	}
	return k;
}
Poly derivative(Poly a){
	Poly res;
	for(int i=1;i<a.size();i++){
		res[i-1]=1ll*a[i]*i%md;
	}
	return res;
}
Poly integral__(Poly a){
	Poly res;
	for(int i=0;i<a.size();i++){
		res[i+1]=1ll*a[i]*inv[i+1]%md;
	}
	return res;
}
Poly rev(Poly a){
	int n=a.size(),siz=1;
	while(siz<n){
		siz<<=1;
	}
	a[siz-1];
	Poly res,tot;
	res[0]=powr(a[0],md-2);
	tot[0]=2;
	while(res.size()<siz){
		Poly ct;
		for(int i=0;i<2*res.size();i++){
			ct[i]=a[i];
		}
		Poly k=1ll*res*(tot-res*ct);
		int ss=res.size();
		for(int i=0;i<ss*2;i++){
			res[i]=k[i];
		}
	}
	Poly cc;
	for(int i=0;i<n;i++){
		cc[i]=res[i];
	}
	return res;
}
Poly Ln(Poly a){
	Poly res=integral__(derivative(a)*rev(a));
	Poly cc;
	for(int i=0;i<a.size();i++){
		cc[i]=res[i];
	}
	return cc;
}
Poly Exp(Poly a){
	int len=a.size();
	Poly res,cnst;
	res[0]=cnst[0]=1;
	int siz=1;
	while(siz<a.size()){
		siz<<=1;
	}
	siz<<=1;
	a[siz-1];
	while(res.size()<siz){
		Poly kt=cnst-Ln(res)+a;
		Poly tmp;
		for(int i=0;i<res.size();i++){
			tmp[i]=kt[i];
		}
		Poly k=tmp*res;
		int cc=res.size();
		for(int i=0;i<cc*2;i++){
			res[i]=k[i];
		}
	}
	Poly cck;
	for(int i=0;i<len;i++){
		cck[i]=res[i];
	}
	return cck;
}
Poly powr(Poly a,int k){
	Poly y=Exp(Ln(a)*k),cc;
	for(int i=0;i<a.size();i++){
		cc[i]=y[i];
	}
	return cc;
}
Poly rt(Poly a){
	Poly res;
	res[0]=1;
	int siz=1,len=a.size();
	while(siz<a.size()){
		siz<<=1;
	}
	siz<<=1;
	a[siz-1];
	while(res.size()<siz){
		Poly kt=a+res*res,tmp;
		for(int i=0;i<res.size();i++){
			tmp[i]=kt[i];
		}
		Poly k=tmp*rev(2*res);
		int cc=res.size();
		for(int i=0;i<cc*2;i++){
			res[i]=k[i];
		}
	}
	Poly rr;
	for(int i=0;i<len;i++){
		rr[i]=res[i];
	}
	return rr;
} 
Poly sin(Poly k){
	int img=powr(3,(md-1)/4);
	Poly kk=Exp(k*img);
	return (kk-rev(kk))*powr(2,md-2)*(md-img);
}
Poly cos(Poly k){
	int img=powr(3,(md-1)/4);
	Poly kk=Exp(k*img);
	return (kk+rev(kk))*powr(2,md-2);
}
Poly asin(Poly k){
	int img=powr(3,(md-1)/4);
	return (md-img)*Ln(rt(1-k*k)+img*k);
}
Poly atan(Poly k){
	int img=powr(3,(md-1)/4);
	return (Ln(1-img*k)-Ln(1+img*k))*img*powr(2,md-2);
}
signed main(){
	int n,t;
	Poly a;
	read(n);
	inv[1]=1;
	for(int i=2;i<=n;i++){
		inv[i]=1ll*(md-md/i)*inv[md%i]%md;
	}
	read(t);
	for(int i=0;i<n;i++){
		read(a[i]);
	}
	if(t){
		Poly res=atan(a);
		for(int i=0;i<n;i++){
			write(res[i]);
			putchar(' ');
		}
	}else{
		Poly res=asin(a);
		for(int i=0;i<n;i++){
			write(res[i]);
			putchar(' ');
		}
	}
	return 0;
}
2022/2/3 19:51
加载中...