首页 > 其他分享 >P7431【THUPC2017】小 L 的计算题 (牛顿恒等式)(分治NTT)(多项式求逆)题解

P7431【THUPC2017】小 L 的计算题 (牛顿恒等式)(分治NTT)(多项式求逆)题解

时间:2024-04-21 21:56:32浏览次数:23  
标签:THUPC2017 return 计算题 int 题解 Poly cs inline mod

知识点涉及:牛顿恒等式,分治 \(NTT\),多项式求逆。

这道题有一个推式子之后分治 \(NTT+Ln+Exp\) 的做法,不过也有一个不用 \(Ln+Exp\) 的做法(理论常数要小点,实际差不多)。

题解:

这道题可以牛顿恒等式直接推出一个非常好写的东西。

首先看一下牛顿恒等式的描述:

对于 \(n\) 次多项式 \(A(x)=\sum_{i=0}^na_ix^i,a_n\neq0\),设 \(b_i=a_{n-i}\),其有 \(n\) 个根 \(x_1,x_2\cdots x_n\),设 \(S_k=\sum_{i=1}^nx_i^k\),则有:

\[\forall t\in \mathbb{N}^*,\sum_{i=1}^tS_ib_{t-i}+tb_t=0 \]

那么这道题要求的东西可以很直接地套上去:

设 \(C(x)=\prod_{i=1}^n(x-a_i)\),则 \(C(x)\) 的根就是 \(a_i\),设其 \(i\) 次项系数为 \(c_i\),\(b_i=c_{n-i}\),\(S_k=\sum_{i=1}^na_i^k\)。则有:

\[\forall t\in \mathbb{N}^*,\sum_{i=1}^tS_ib_{t-i}=-tb_t \]

左边是一个卷积的形式,乘到右边就是多项式求逆,可以直接得到 \(S\) 的生成函数。

代码

#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<22|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; 
	}
	template<typename T>
	inline T get(){
		char c;T num;
		while(!isdigit(c=gc()));num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline int gi(){return get<int>();}
}
using namespace IO;

using std::cerr;
using std::cout;

cs int mod=998244353;
inline int add(int a,int b){a+=b-mod;return a+(a>>31&mod);}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline int power(int a,int b,int res=1){
	for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));
	return res;
}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}

typedef std::vector<int> Poly;

cs int bit=19,SIZE=1<<bit|1;

int r[SIZE],*w[bit+1];
inline void init_NTT(){
	for(int re i=1;i<=bit;++i)w[i]=new int[1<<i-1];
	int wn=power(3,mod-1>>bit);w[bit][0]=1;
	for(int re i=1;i<(1<<bit-1);++i)w[bit][i]=mul(w[bit][i-1],wn);
	for(int re i=bit-1;i;--i)
	for(int re j=0;j<(1<<i-1);++j)w[i][j]=w[i+1][j<<1];
}
inline void NTT(int *A,int len,int typ){
	for(int re i=1;i<len;++i)if(i<r[i])std::swap(A[i],A[r[i]]);
	for(int re i=1,d=1;i<len;i<<=1,++d)
	for(int re j=0;j<len;j+=i<<1)
	for(int re k=0;k<i;++k){
		int &t1=A[j+k],&t2=A[i+j+k],t=mul(t2,w[d][k]);
		t2=dec(t1,t),Inc(t1,t);
	}
	if(typ==-1){
		std::reverse(A+1,A+len);
		for(int re i=0,inv=power(len,mod-2);i<len;++i)Mul(A[i],inv);
	}
}
inline void NTT(Poly &A,int len,int typ){NTT(&A[0],len,typ);}
inline void init_rev(int l){
	for(int re i=1;i<l;++i)r[i]=r[i>>1]>>1|((i&1)?l>>1:0);
}

inline Poly operator*(cs Poly &a,cs Poly &b){
	int n=a.size(),m=b.size(),deg=n+m-1,l=1;
	static int A[SIZE],B[SIZE];
	while(l<deg)l<<=1;init_rev(l);
	memcpy(A,&a[0],sizeof(int)*n);
	memset(A+n,0,sizeof(int)*(l-n));
	memcpy(B,&b[0],sizeof(int)*m);
	memset(B+m,0,sizeof(int)*(l-m));
	NTT(A,l,1);NTT(B,l,1);
	for(int re i=0;i<l;++i)Mul(A[i],B[i]);
	NTT(A,l,-1);return Poly(A,A+deg);
}

inline Poly Inv(cs Poly &a,int lim=-1){
	int n=a.size();if(lim==-1)lim=n;
	Poly c,b(1,power(a[0],mod-2));
	for(int re l=4;(l>>2)<lim;l<<=1){
		init_rev(l);
		c.resize(l>>1);for(int re i=0;i<(l>>1);++i)c[i]=i<n?a[i]:0;
		c.resize(l),NTT(c,l,1);
		b.resize(l),NTT(b,l,1);
		for(int re i=0;i<l;++i)Mul(b[i],dec(2,mul(b[i],c[i])));
		NTT(b,l,-1);b.resize(l>>1);
	}b.resize(lim);
	return b;
}

int n;

inline Poly solve(int l,int r){
	if(l==r){
		Poly c;c.resize(2);
		c[1]=1;
		c[0]=dec(mod,gi());
		return c;
	}int mid=l+r>>1;
	return solve(l,mid)*solve(mid+1,r);
}

signed main(){
	init_NTT();int T=gi();
	while(T--){
		n=gi();
		Poly F=solve(1,n);
		std::reverse(F.begin(),F.end());
		Poly G;G.resize(n+1);
		for(int re i=0;i<=n;++i)G[i]=mul(F[i],mod-i);
		G=G*Inv(F);int ans=0;
		for(int re i=1;i<=n;++i)ans^=G[i];
		cout<<ans<<"\n";
	}
	return 0;
}//码风独特

标签:THUPC2017,return,计算题,int,题解,Poly,cs,inline,mod
From: https://www.cnblogs.com/BadBadBad/p/18149572/P7431

相关文章

  • CF1067E Random Forest Rank 题解
    这道题涉及了组合分析和概率。本质上,当以一定的概率从给定的树中删除边时,您需要找到结果林的邻接矩阵的期望秩。要解决这个问题,可以使用动态规划。我们用\(f(u,v)\)表示当删除边\((u,v)\)时,由以顶点\(v\)为根的子树中的顶点形成的林的期望秩。这里,\(u\)和\(v\)是树中的......
  • 2024年GPLT团体程序设计比赛L2-D吉利矩阵题解
    只能说比赛时前期做得太慢了,后面导致题目只能捞点分数(IOI赛制),当时这道题是我不剪枝DFS拿了4分,压线拿铜牌!考完试一做,发现是个大水题(bushi)主要原理:DFS(深度优先搜索)+剪枝名言:学搜索核心就是学剪枝废话不说了,见代码点击查看代码//原理:DFS+剪枝#include<bi......
  • Atcoder ABC 350 全题解
    题外话别以为博主之前几场ABC都咕咕咕了,最近状态不好,这次ABC终于回来了(也有可能是题目变容易了,有图为证)P.S.请耐心看到最后!!否则后果自负!!!AB这年头谁不会AB啊当然有。不学OI的人。C考虑选择排序,依次将$1,2,3\cdots$与它们应该在的位置进行交换。那如果真的......
  • 题解:CF17D Notepad
    由于首位不能是\(0\),因此首位有\(b-1\)种可能性。其他\(n-1\)位有\(b^{n-1}\)种可能。因此这些数总计\((b-1)b^{n-1}\)每页\(c\)个数,求最后一页有多少个数,即求\(\text{ans}=(b-1)b^{n-1}\quad\bmodc\)注意到题目中\(b,n\)都非常大,采用扩展欧拉定理进行降......
  • [ZJOI2019] 语言 题解
    不愧是\(ZJOI\),《最可做的一道题》都让人一头雾水……首先将问题转化到链上。可以将总共的组数转化为每个点可以到达的城市。明显给每个点建一棵动态开点线段树,维护可以和他通商的点。很明显,可以通商的点的标号连续的一段。我们可以将可以将每一次传播语言的工作当作区间修改......
  • 【题解】[NOIP2001 普及组] 装箱问题
    [NOIP2001普及组]装箱问题这是一道动态规划题。那就先定义状态吧(这里用的是一维滚动数组)。$f[j]$代表当我有$j$这么多容量可以用时,能装的最大重量是多少。好,状态定义好了再想状态转移方程。$f[j]$可以从哪里转移过来呢?想一想,当我们循环到第$i$个物品时,我们面临两个......
  • 简单的数学题 题解
    题意:解方程\[a^x\equivx\pmodm\]数据范围:\(a<m\le10^9\)Solution首先\(a^x\equiva^{x\bmod\varphi(m)+\varphi(m)}\pmodm\)我们设\(\text{solve}(\&x,y,m)\)表示解决\[a^{x\bmod\varphi(m)+y}\equivx\pmodm\]原题即\(\text{solve}(\&x,......
  • 数表 题解
    “当你想不出来一道题的时候就想一下排序”先不考虑\(a\),求\[\begin{aligned}&\sum_{i=1}^n\sum_{j=1}^m\sigma_1(\gcd(i,j))\\=&\sum_{i=1}^n\sum_{j=1}^m\sum_{d=1}^{\min(n,m)}[d=\gcd(i,j)]\sigma_1(d)\\=&\sum_{d=1}^{\min(n,m)}\sigma_1(d)\sum_......
  • 最大幂指数 题解
    Statement\(f(x)\)表示\(x\)所含质因子的最大幂指数,对于\(T=10^4\),\(a,b\le10^7\),求\[\sum_{i=1}^a\sum_{j=1}^bf(\gcd(i,j))\]时限2sSolution\[\begin{aligned}&\sum_{i=1}^a\sum_{j=1}^bf(\gcd(i,j))\\=&\sum_{i=1}^a\sum_{j=1}^b\sum_{......
  • 一个人的数论 题解
    Solution令指数为\(k\)正常反演得到\[\sum_{d\midn}\mu(d)d^k\sum_{i=1}^{\fracnd}i^k\]设\(f(x)=\sum_{i=1}^xi^k\),它是一个关于\(x\)的\(k+1\)次多项式求这个多项式可以插值\(\mathcalO(n^2)\)(推荐)高斯消元(待定系数法)\(\mathcalO(n^3)\)直接伯努利数\(\ma......