烷基计数加强版加强版
时间:2020-05-09
本文章向大家介绍烷基计数加强版加强版,主要包括烷基计数加强版加强版使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
烷基计数加强版加强版
定义\(F(x)\)表示答案多项式
枚举一个点为根,那么我们可以列出\(F(x)\)的转移方程
\(F(x)=x\frac{F(x)^3+3F(x^2)F(x)+2F(x^3)}{6}+1\)
我们考虑解这个方程牛顿迭代法
\[f(F(x))=F(x)-x\frac{F(x)^3+3F(x^2)F(x)+2F(x^3)}{6}-1
\]
\[f'(F(x))=1-\frac{x}{6}(3F(x)^2+3F(x^2))
\]
预先求出\(G(x) = F(x) (\mod x^\frac{n}{2})\)
可以直接求出\(F(x^2),F(x^3)\),所以我们认为\(F(x^2),F(x^3)\)是常数
设\(F(x^2)=A,F(x^3)=B\)
\(f(F)=F-x\frac{F^3+3A\cdot F+2B}{6}-1=0\)
\[f'(F)=1-\frac{x}{6}(3F^2+3A)=0
\]
求出多项式\(f(F(x))\)在\(G(x)\)上的泰勒展开
\[f(F(x))=\sum _0^\infty \frac{f^{(i)}(G)}{i!}(F(x)-G(x))^i
\]
\(i=0,f(G)\)
\[i=1,f'(G)(F-G)
\]
\(i>1,(F-G)^i\equiv 0 (\mod x^n)\)
\(0=f(G)+f'(G)(F-G)\)
\(F=G-\frac{f(G)}{f'(G)}\)
\[F=G-\frac{G-\frac{x}{6}(G^3+3A\cdot G+2B)-1}{1-\frac{x}{6}(3G^2+3A)}
\]
\[F=\frac{G-\frac{x}{6}(3G^3+3A\cdot G)-G+\frac{x}{6}(G^3+3A\cdot G+2B)+1}{1-\frac{x}{6}(3G^2+3A)}
\]
\[F=\frac{\frac{x}{6}(2B-2 G^3)+1}{1-\frac{x}{6}(3G^2+3A)}
\]
代码,上面全部都是多项式的模板
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cctype>
#include<vector>
using namespace std;
#define reg register
typedef long long ll;
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
#define pb push_back
template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
char IO;
template<class T=int> T rd(){
T s=0;
int f=0;
while(!isdigit(IO=getchar())) if(IO=='-') f=1;
do s=(s<<1)+(s<<3)+(IO^'0');
while(isdigit(IO=getchar()));
return f?-s:s;
}
const int N=1<<21|10,P=998244353;
int n;
ll qpow(ll x,ll k) {
ll res=1;
for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
return res;
}
namespace Polynomial{
typedef vector <int> Poly;
#define Mod1(x) ((x>=P)&&(x-=P))
#define Mod2(x) ((x<0)&&(x+=P))
void Show(Poly a){ for(int i:a) printf("%d ",i); puts(""); }
int rev[N];
int PreMake(int n){
int R=1,cc=-1;
while(R<n) R<<=1,cc++;
rep(i,1,R-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<cc);
return R;
}
void NTT(int n,Poly &a,int f){
rep(i,0,n-1) if(rev[i]<i) swap(a[i],a[rev[i]]);
for(int i=1;i<n;i<<=1) {
int w=qpow(f==1?3:(P+1)/3,(P-1)/i/2);
for(int l=0;l<n;l+=i*2) {
ll e=1;
for(int j=l;j<l+i;++j,e=e*w%P) {
int t=a[j+i]*e%P;
a[j+i]=a[j]-t,Mod2(a[j+i]);
a[j]+=t,Mod1(a[j]);
}
}
}
if(f==-1) {
ll base=qpow(n,P-2);
rep(i,0,n-1) a[i]=a[i]*base%P;
}
}
Poly operator * (Poly a,Poly b){
int n=a.size()+b.size()-1,R=PreMake(n);
a.resize(R),b.resize(R);
NTT(R,a,1),NTT(R,b,1);
rep(i,0,R-1) a[i]=1ll*a[i]*b[i]%P;
NTT(R,a,-1);
a.resize(n);
return a;
}
Poly operator + (Poly a,Poly b) {
int n=max(a.size(),b.size());
a.resize(n),b.resize(n);
rep(i,0,a.size()-1) a[i]+=b[i],Mod1(a[i]);
return a;
}
Poly operator - (Poly a,Poly b) {
int n=max(a.size(),b.size());
a.resize(n),b.resize(n);
rep(i,0,a.size()-1) a[i]-=b[i],Mod2(a[i]);
return a;
}
Poly Inv(Poly a) {
int n=a.size();
if(n==1) { Poly tmp; tmp.pb(qpow(a[0],P-2)); return tmp; }
Poly b=a; b.resize((n+1)/2); b=Inv(b);
int R=PreMake(n<<1);
a.resize(R),b.resize(R);
NTT(R,a,1),NTT(R,b,1);
rep(i,0,R-1) a[i]=(2-1ll*a[i]*b[i]%P+P)*b[i]%P;
NTT(R,a,-1);
a.resize(n);
return a;
}
Poly operator / (vector <int> a,vector <int> b){
reverse(a.begin(),a.end()),reverse(b.begin(),b.end());
int n=a.size(),m=b.size();
b.resize(n-m+1),b=Inv(b);
a=a*b,a.resize(n-m+1);
reverse(a.begin(),a.end());
return a;
}
Poly operator % (vector <int> a,vector <int> b) {
a=a-a/b*b;
a.resize(b.size()-1);
return a;
}
Poly Sqrt(vector <int> a){
int n=a.size();
if(n==1) { Poly tmp; tmp.pb(1); return tmp; }
Poly b=a; b.resize((n+1)/2),b=Sqrt(b),b.resize(n);
Poly c=Inv(b);
int R=PreMake(n*2);
a.resize(R),c.resize(R);
NTT(R,a,1),NTT(R,c,1);
rep(i,0,R-1) a[i]=1ll*a[i]*c[i]%P;
NTT(R,a,-1);
a.resize(n);
rep(i,0,n-1) a[i]=1ll*(P+1)/2*(a[i]+b[i])%P;
return a;
}
Poly Deri(Poly a){
rep(i,1,a.size()-1) a[i-1]=1ll*i*a[i]%P;
a.pop_back();
return a;
}
int Mod_Inv[N];
Poly IDeri(Poly a) {
Mod_Inv[0]=Mod_Inv[1]=1;
rep(i,2,a.size()+1) Mod_Inv[i]=1ll*(P-P/i)*Mod_Inv[P%i]%P;
a.pb(0);
drep(i,a.size()-1,1) a[i]=1ll*a[i-1]*Mod_Inv[i]%P;
a[0]=0;
return a;
}
Poly Ln(Poly a){
int n=a.size();
a=Inv(a)*Deri(a);
a.resize(n-1);
return IDeri(a);
}
Poly Exp(Poly a){
int n=a.size();
if(n==1) { Poly tmp; tmp.pb(1); return tmp; }
Poly b=a; b.resize((n+1)/2),b=Exp(b),b.resize(n);
Poly c=Ln(b);
int R=PreMake(n<<1);
a.resize(R),b.resize(R),c.resize(R);
NTT(R,b,1),NTT(R,a,1),NTT(R,c,1);
rep(i,0,R-1) a[i]=1ll*b[i]*(1-c[i]+a[i]+P)%P;
NTT(R,a,-1),a.resize(n);
return a;
}
}
using namespace Polynomial;
const int Inv6=qpow(6,P-2);
const int Inv3=(P+1)/3;
const int Inv2=(P+1)/2;
Poly Calc(int n){
if(n==1) return Poly{1};
int m=(n+1)>>1;
Poly G=Calc(m),A,B;
A.resize(n),B.resize(n);
rep(i,0,(n-1)/2) A[i*2]=G[i];
rep(i,0,(n-1)/3) B[i*3]=G[i];
Poly x=Poly{1}+Poly{0,Inv3}*(B-G*G*G);
Poly y=Poly{1}-Poly{0,Inv2}*(G*G+A);
x=x*Inv(y);
x.resize(n);
return x;
}
int main(){
int n=rd();
Poly Res=Calc(n+1);
printf("%d\n",Res[n]);
}
原文地址:https://www.cnblogs.com/chasedeath/p/12859198.html
- 微信小程序中用户唯一ID的获取
- Mysql备份系列(2)--mysqldump备份(全量+增量)方案操作记录
- Enterprise Library 4.1学习笔记1----配置应用程序块(c/s和b/s均适用)
- 简单账本-用完即走的微信小程序
- 新技术革命和新产业变革正进行 “互联网+大数据+人工智能+”时代正到来
- 微信小程序开发及相关设置小结
- gitlab两种连接方式:ssh和http配置介绍
- C#实现微信AES-128-CBC加密数据的解密
- UrlReferrer为空的问题?
- DeepMind发文回顾2017:AlphaGo团队已迎战下一个重大挑战
- [你必须知道的.Net]读书笔记--浅clone与深clone
- Python基础语法学习整理
- 通过部分感知深度卷积网络进行人脸特征点定位
- [你必须知道的.Net]读书笔记--override与new在继承中的区别
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法