【XSY2772】数列 特征多项式 数学
题目描述
给你一个数列:
a^n&1\leq n\leq k\\
\sum_{i=1}^k(a-1)f_{n-i}&n>k
\end{cases}
\]
记\(g_i\)为当\(k=i\)时\(f_n\)的值,求
\]
对于\(60\%\)的数据:\(m\leq 200,n\leq {10}^9\)
对于另外\(40\%\)的数据:\(m\leq {10}^9,n\leq 3\times {10}^6\)
题解
第一部分
直接按常系数线性递推的通用做法来做。
可以不用FFT。
时间复杂度:\(O(m^3\log n)\)或\(O(m^2\log m\log n)\)
第二部分
因为当\(i\geq n\)时\(g_i=a^n\),所以我们只需要求\(g_1\ldots g_{n-1}\)
f_n&=af_{n-1}-(a-1)f_{n-m-1}\\
F(x)&=axF(x)-(a-1)x^{k+1}F(x)+ax-ax^{k+1}\\
(1-ax+(a-1)x^{k+1})F(x)&=ax-ax^{k+1}\\
F(x)&=\frac{ax-ax^{k+1}}{1-ax+(a-1)x^{k+1}}\\
&=(ax-ax^{k+1})\sum_{i=0}^\infty\sum_{j=0}^i\binom{i}{j}{(1-a)}^jx^{j(k+1)}a^{i-j}x^{i-j}\\
\end{align}
\]
记
\]
那么
F(x)&=(ax-ax^{k+1})G(x)\\
[x^n]F(x)&=a[x^{n-1}]G(x)-a[x^{n-k-1}]G(x)\\
[x^n]G(x)&=[x^n]\sum_{i=0}^\infty\sum_{j=0}^i\binom{i}{j}{(1-a)}^ja^{i-j}x^{jk+i}\\
&=\sum_{j}\sum_{i=n-jk}\binom{i}{j}{(1-a)}^ja^{i-j}\\
&=\sum_{j}\binom{n-jk}{j}{(1-a)}^ja^{n-j(k+1)}\\
\end{align}
\]
观察到对于所有的\(k\),\(j\)的取值总共有\(O(n\log n)\)种,所以可以暴力枚举\(k,j\)。
时间复杂度:\(O(n\log n+\log m)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
#include<iostream>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
s=c-'0';
while((c=getchar())>='0'&&c<='9')
s=s*10+c-'0';
return s;
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
const ll p=998244353;
const ll vv=19260817;
ll fp(ll a,ll b)
{
ll s=1;
for(;b;b>>=1,a=a*a%p)
if(b&1)
s=s*a%p;
return s;
}
int n,k,m;
ll pw[100010];
ll c[510];
ll d[510];
ll e[510];
int len;
void mul()
{
static ll f[510];
for(int i=0;i<=2*len;i++)
f[i]=0;
for(int i=0;i<len;i++)
for(int j=0;j<len;j++)
f[i+j]=(f[i+j]+d[i]*d[j])%p;
for(int i=0;i<2*len;i++)
d[i]=f[i];
}
void mod()
{
for(int i=2*len;i>=len;i--)
if(d[i])
{
ll v=d[i];
for(int j=0;j<=len;j++)
d[i-len+j]=(d[i-len+j]-v*c[j])%p;
}
}
void pow(int n)
{
if(!n)
return;
pow(n>>1);
mul();
if(n&1)
{
for(int i=2*len;i>=1;i--)
d[i]=d[i-1];
d[0]=0;
}
mod();
}
ll calc1(int x)
{
len=x;
memset(d,0,sizeof d);
d[0]=1;
c[x]=1;
for(int i=0;i<x;i++)
c[i]=-k+1;
pow(n-1);
ll ans=0;
for(int i=1;i<=x;i++)
ans=(ans+pw[i]*d[i-1])%p;
return ans;
}
void solve1()
{
ll ans=0;
pw[0]=1;
for(int i=1;i<=m;i++)
pw[i]=pw[i-1]*k%p;
for(int i=m;i>=1;i--)
ans=(ans+calc1(i))*vv%p;
ans=(ans+p)%p;
printf("%lld\n",ans);
}
int fac[3000010];
int inv[3000010];
int ifac[3000010];
int s1[3000010];
int s2[3000010];
int getc(int x,int y)
{
return (ll)fac[x]*ifac[y]%p*ifac[x-y]%p;
}
int gao(int n,int m)
{
int s=0;
for(int i=0;i*(m+1)<=n;i++)
s=(s+(ll)fac[n-i*m]*s1[i]%p*s2[n-i*(m+1)])%p;
return s;
}
void solve2()
{
inv[1]=fac[0]=fac[1]=ifac[0]=ifac[1]=1;
for(int i=2;i<=3000000;i++)
fac[i]=(ll)fac[i-1]*i%p;
s1[0]=1;
for(int i=1;i<=3000000;i++)
s1[i]=(ll)s1[i-1]*(1-k)%p;
s2[0]=1;
for(int i=1;i<=3000000;i++)
s2[i]=(ll)s2[i-1]*k%p;
for(int i=2;i<=3000000;i++)
{
inv[i]=(ll)-p/i*inv[p%i]%p;
ifac[i]=(ll)ifac[i-1]*inv[i]%p;
s1[i]=(ll)s1[i]*ifac[i]%p;
s2[i]=(ll)s2[i]*ifac[i]%p;
}
ll ans=0;
if(n<=m)
{
for(int i=n-1;i>=1;i--)
ans=(ans+gao(n-1,i)-gao(n-i-1,i))*vv%p;
ans=ans*k%p;
ll v=fp(k,n)*(fp(vv,m+1)-fp(vv,n))%p*fp(vv-1,p-2)%p;
ans=(ans+v)%p;
ans=(ans+p)%p;
}
else
{
for(int i=m;i>=1;i--)
ans=(ans+gao(n-1,i)-gao(n-i-1,i))*vv%p;
ans=ans*k%p;
ans=(ans+p)%p;
}
printf("%lld\n",ans);
}
int main()
{
open("a");
scanf("%d%d%d",&m,&k,&n);
if(m<=200)
solve1();
else
solve2();
return 0;
}
【XSY2772】数列 特征多项式 数学的更多相关文章
- BZOJ- 3142:数列 (数学)
题意:给出N,K,M,P.求有多少长度为K的序列A,满足:(1)首项为正整数:(2)递增数列:(3)相邻两项的差小于等于m:(4)最后一个数小于等于N. 思路:根据差分来算数量. #include&l ...
- [CSP-S模拟测试]:数列(数学)
题目传送门(内部题95) 输入格式 第一行三个整数$n,a,b$,第二行$n$个整数$x_1\sim x_n$表示数列. 输出格式 一行一个整数表示答案.无解输出$-1$. 样例 样例输入:2 2 3 ...
- ACM/ICPC 之 数论-斐波拉契●卢卡斯数列(HNNUOJ 11589)
看到这个标题,貌似很高大上的样子= =,其实这个也是大家熟悉的东西,先给大家科普一下斐波拉契数列. 斐波拉契数列 又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.… ...
- python学习第四十四天斐波那契数列和yield关键词使用
斐波那契数列是数学中的常见的算法,第一个第二个不算,从第三个开始,每个数的都是前面两个数的和,使用yield关键词把生成的数列保存起来,调用的时候再调用,下面举例说明一下 def fab(max): ...
- 关于Haskell计算斐波那契数列的思考
背景 众所周知,Haskell语言是一门函数式编程语言.函数式编程语言的一大特点就是数值和对象都是不可变的,而这与经常需要对状态目前的值进行修改的动态规划算法似乎有些"格格不入", ...
- fibnacci数列的python实现
费波那契数列(Successione di Fibonacci) 又译为费波拿契数.斐波那契数列.费氏数列.黄金分割数列 在数学上,费波那契数列是以递归的方法来定义: 用文字来说,就是费波那契数列由0 ...
- Python中利用函数装饰器实现备忘功能
Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下 " ...
- # 【Python3练习题 007】 有一对兔子,从出生后第3个月起每个月都生一对兔子, # 小兔子长到第三个月后每个月又生一对兔子, # 假如兔子都不死,问每个月的兔子总数为多少?
# 有一对兔子,从出生后第3个月起每个月都生一对兔子,# 小兔子长到第三个月后每个月又生一对兔子, # 假如兔子都不死,问每个月的兔子总数为多少?这题反正我自己是算不出来.网上说是经典的“斐波纳契数列 ...
- C++ one more time
写在前面:我们学习程序设计的方法先是模仿,然后举一反三.在自己的知识面还没有铺开到足够解决本领域的问题时,不要将精力过分集中于对全局无足轻重的地方!!! 以下参考钱能老师的<C++程序设计教程 ...
随机推荐
- Bean笔记
为什么需要Bean , 因为 Aop 需要. 顺序 InstantiationAwareBeanPostProcessor , BeanPostProcessor 每个Bean都会执行这两个组件的相关 ...
- Python入门-Hello Word
1.python语言介绍 Python创始人:Guido Van Rossum 2.python是一种解释型.动态类型计算机程序设计语言. 解释型:程序无需编译成二进制代码,而是在执行时对语句一条一条 ...
- D - Nature Reserve(cf514,div2)
题意:给出n(n<=1e5)个点,求一个最小的圆,与x轴相切,并且包含这n个点 思路:我第一想到的是,这个圆一定会经过一个点,再根据与x轴相切,我们可以找到最小的圆,让它包含其余的点,但是如何判 ...
- Tea Party CodeForces - 808C (构造+贪心)
Polycarp invited all his friends to the tea party to celebrate the holiday. He has ncups, one for ea ...
- p201 谱集是闭集 有界集
1 是如何来的? 由1 如何推出 2 2 是如何来的?谢谢 1.σ是的补集 入属于ρ 稠密是因为 T有定义的地方,λI-T都有定义,有界是因为 所以 然后 ρ是σ的补集 模比||T||大的数都 ...
- 访问修饰符 public private protected default
- 转:Linux(Centos)之安装Nginx及注意事项
1.Nginx的简单说明 a. Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器,期初开发的目的就是为了代理电子邮件服务器室友:Igor Sysoev开发 ...
- 配置router列表
import Vue from "vue"; import VueRouter from 'vue-router'; import Star from '../components ...
- laravel自定义门面
https://learnku.com/articles/19195 关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己 ...
- Jenkins配置权限管理
借鉴博客:https://www.cnblogs.com/Eivll0m/p/6734076.html 懒得写了,照上面是配置成功了,弄了权限角色与用户的配置