【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++程序设计教程 ...
随机推荐
- python读取/创建XML文件
Python中定义了很多处理XML的函数,如xml.dom,它会在处理文件之前,将根据xml文件构建的树状数据存在内存.还有xml.sax,它实现了SAX API,这个模块牺牲了便捷性,换取了速度和减 ...
- Git_GitHub详解
Git和Github详细教程 一 概述 说到Git和Github,前几天我们知道微软以75亿美元收购全球最大的代码托管和写作平台GitHub,而GitHub是全球最大的代码仓库,很多开发人员都将代码 ...
- django 路由系统,数据库操作
一.修改配置 数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dbname', 'USER': ...
- openstack-KVM安装与使用
一.KVM安装 1.安装条件 VT-x BIOS Intel9R) Virtualization Tech [Enabled] cat /proc/cpuinfo | grep -e vmx -e n ...
- haoop笔记
: //:什么是hadoop? hadoop是解决大数据问题的一整套技术方案 :hadoop的组成? 核心框架 分布式文件系统 分布式计算框架 分布式资源分配框架 hadoop对象存储 机器计算 :h ...
- socket通信原理三次握手和四次握手详解
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1. 什么是TCP/IP.UDP?2. Sock ...
- js的日期操作:String转date日期格式、求日期差
一.在js中String类型转成date格式 var date = new Date("2018-9-21 14:58:43");//就是这么简单 二.date转String类型就 ...
- Python 爬虫 解析库的使用 --- Beautiful Soup
知道了正则表达式的相关用法,但是一旦正则表达式写的有问题,得到的可能就不是我们想要的结果了.而且对于一个网页来说,都有一定的特殊结构和层级关系,而且有很多节点都有id或class来做区分,所以借助它们 ...
- 安装splash
参考: https://blog.csdn.net/qq_41020281/article/details/82599075
- CSS自定义属性expression_r
CSS的出现使网页制作者在对网页元素的控制方便许多,当然,有利必有弊,CSS只能对颜色.大小.距离等静态样式有效,对于要实现某些html元素的动态样式就显得有些力不从心.有了CSS的自定义属性expr ...