【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++程序设计教程 ...
随机推荐
- position fixed 相对于父级定位
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- getQueryStringByName url参数/
MasterId: (masterIdUrl != null && masterIdUrl != "") ? masterIdUrl : null ClassId: ...
- dynamo与cassandra区别
虽说cassandra是dynamo的开源版本,但两者还是有很大区别的. coordinator的选取: 在dynamo论文中,一般是preference list中N个副本的第一个 为什么叫“一般” ...
- js手机短信验证
贴代码之前,我们先讲一下这里我们用到的技术主要有1个.setInterval(),这个方法可以实现倒计时的效果. css: .weui_btn_disabled.weui_btn_default { ...
- oracle小记:dba_data_files
今天给表空间扩展的时候,使用了dba_data_files进行查询.查阅了网上的资料. 该系统系统中含有以下字段 每个字段的含义如下:
- 11 The superlative
1 最高级用来表明三个或更多事物之间的关系.最高级是通过在形容词之前加 "the" 并在之后加 "-est",或在形容词之前加 "the most&q ...
- Storm原理
zookeeper是对称结构
- HTML5 History API & URL 重定向
HTML5 History API & URL 重定向 disabled server url redirect https://developer.mozilla.org/en-US/doc ...
- Lodop打印设计(PRINT_DESIGN)介绍
打印设计(PRINT_DESIGN)界面上方有两栏菜单栏,举例说明(文本框,条码,图形等).(1)第一排最左侧第一个功能,位置移动:控制里面元素微上下左右移动,每次移动一个px.(用于微调,普通调整可 ...
- 用于Azure功能的Visual Studio 2017工具
今天我们很高兴地宣布发布第一个预览的Visual Studio 2017工具的Azure功能.这个预览介绍了一些令人兴奋的变化,我们以前的版本.此外,除了支持Visual Studio 2017之外, ...