Codeforces 1096G. Lucky Tickets NTT

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36797646/article/details/85637710

题解:

就是一个裸的背包,用快速幂+NTT优化就行了,当练练手。

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=200010,Maxk=12;
const int inf=2147483647;
const int mod=998244353,gn=3;
int read()
{
	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<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
int Pow(int x,int y)
{
	if(!y)return 1;
	int t=Pow(x,y>>1),re=(LL)t*t%mod;
	if(y&1)re=(LL)re*x%mod;
	return re;
}
int rev[Maxn*14];
void ntt(int *a,int n,int op)
{
	for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
	for(int i=1;i<n;i<<=1)
	{
		int wn;
		if(op==1)wn=Pow(gn,(mod-1)/(i<<1));
		else wn=Pow(gn,mod-1-(mod-1)/(i<<1));
		for(int j=0;j<n;j+=(i<<1))
		{
			int w=1;
			for(int k=0;k<i;k++)
			{
				int t=(LL)a[i+j+k]*w%mod;w=(LL)w*wn%mod;
				a[i+j+k]=(a[j+k]-t+mod)%mod;
				a[j+k]=(a[j+k]+t)%mod;
			}
		}
	}
	if(op==-1)
	{
		int inv=Pow(n,mod-2);
		for(int i=0;i<n;i++)a[i]=(LL)a[i]*inv%mod;
	}
}
int n,k,g[Maxn*14],f[Maxn*14];
void f_Pow()
{
	int m=n>>1;bool fir=true;
	int N=1;while(N<=m*9)N<<=1;
	rev[0]=0;for(int i=1;i<N;i++)rev[i]=((rev[i>>1]>>1)|((i&1)*(N>>1)));
	ntt(g,N,1);
	while(m)
	{
		if(m&1)
		{
			if(fir)
			{
				fir=false;
				for(int i=0;i<N;i++)f[i]=g[i];
			}
			else 
			{
				for(int i=0;i<N;i++)f[i]=(LL)f[i]*g[i]%mod;
			}
		}
		for(int i=0;i<N;i++)g[i]=(LL)g[i]*g[i]%mod;
		m>>=1;
	}
	ntt(f,N,-1);
}
int main()
{
	memset(g,0,sizeof(g));
	n=read(),k=read();
	for(int i=1;i<=k;i++)g[read()]=1;
	f_Pow();
	int ans=0;
	for(int i=0;i<=(n>>1)*9;i++)ans=(ans+(LL)f[i]*f[i]%mod)%mod;
	printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/baidu_36797646/article/details/85637710