LOJ#3090. 「BJOI2019」勘破神机

为了这题我去学习了一下BM算法。。

很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列

3的地方是\(G_{1} = 3,G_{2} = 11\)其中下标表示长度的\(\frac{1}{2}\),可以得到\(G_{3} = 4G_{2} - G_{1}\)

然后我们列一波特征根方程,可以得到

\(m = 2\)时

\[\left\{\begin{matrix}
x_{1} = \frac{1 + \sqrt{5}}{2}
\\ x_{2} = \frac{1 - \sqrt{5}}{2}
\\ c_{1} = \frac{5 + \sqrt{5}}{10}
\\ c_{2} = \frac{5 - \sqrt{5}}{10}

\end{matrix}\right.
\]

\(m = 3\)时

\[\left\{\begin{matrix}
x_{1} = 2 + \sqrt{3}
\\ x_{2} = 2 - \sqrt{3}
\\ c_{1} = \frac{3 + \sqrt{3}}{6}
\\ c_{2} = \frac{3 - \sqrt{3}}{10}

\end{matrix}\right.
\]

然后我们会可以把阶乘\(n(n - 1)(n - 2)...(n - k + 1)\)当成一个k次多项式

然后暴力算出每一项的系数,然后我们要算的就是

\(\sum_{i = l}^{r} f_{i}^{k}\)

然后把通项带进去

\(\sum_{i = l}^{r} (c_{1}x_{1}^{i} + c_{2}x_{2}^{i})^{k}\)

\(\sum_{i = l}^{r}\sum_{j = 0}^{k}\binom{k}{j}c_{1}^{j}x_{1}^{ij}c_{2}^{k - j}x_{2}^{i(k - j)}\)

\(\sum_{j = 0}^{k}\binom{k}{j}c_{1}^{j}c_{2}^{k - j}\sum_{i = l}^{r}(x_{1}^{j}x_{2}^{k - j})^{i}\)

后面是等比数列求和,算一下就好了

复杂度是\(k^{2}\log r\)的

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 2005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 998244353;
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
void update(int &x,int y) {
x = inc(x,y);
}
int fpow(int x,int c) {
int res = 1,t = x;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
template<int T>
struct Complex {
int r,i;
Complex(int _r = 0,int _i = 0) {r = _r;i = _i;}
friend Complex operator + (const Complex &a,const Complex &b) {
return Complex(inc(a.r,b.r),inc(a.i,b.i));
}
friend Complex operator - (const Complex &a,const Complex &b) {
return Complex(inc(a.r,MOD - b.r),inc(a.i,MOD - b.i));
}
friend Complex operator * (const Complex &a,const Complex &b) {
return Complex(inc(mul(a.r,b.r),mul(T,mul(a.i,b.i))),inc(mul(a.r,b.i),mul(b.r,a.i)));
}
friend Complex fpow(Complex x,int64 c) {
Complex res(1,0),t = x;
while(c) {
if(c & 1) res = res * t;
t = t * t;
c >>= 1;
}
return res;
}
friend Complex Query(Complex x,int64 n) {
if(x.r == 1 && !x.i) return (n + 1)% MOD;
Complex u = 1 - fpow(x,n + 1),d = 1 - x,t;
t = d;t.i = MOD - t.i;
int iv = fpow((t * d).r,MOD - 2);
u = u * t * iv;
return u;
}
};
int m,k,f[1005],fac[1005],invfac[1005];
int64 l,r;
int C(int n,int m) {
if(n < m) return 0;
return mul(fac[n],mul(invfac[m],invfac[n - m]));
}
namespace mequal2 {
Complex<5> x1,x2,c1,c2;
void Main() {
int inv2 = fpow(2,MOD - 2),inv10 = fpow(10,MOD - 2);
x1 = Complex<5>(inv2,inv2);x2 = Complex<5>(inv2,MOD - inv2);
c1 = Complex<5>(mul(5,inv10),inv10);c2 = Complex<5>(mul(5,inv10),MOD - inv10);
int ans = mul(invfac[k],fpow((r - l + 1) % MOD,MOD - 2));
Complex<5> res;
for(int j = 1 ; j <= k ; ++j) {
Complex<5> s;
for(int h = 0 ; h <= j ; ++h) {
Complex<5> t = C(j,h) * fpow(c1,h) * fpow(c2,j - h),q = fpow(x1,h) * fpow(x2,j - h),p;
p = Query(q,r) - Query(q,l - 1);
s = s + t * p;
}
res = res + s * f[j];
}
ans = mul(ans,res.r);
out(ans);enter;
}
}
namespace mequal3 {
Complex<3> x1,x2,c1,c2;
void Main() {
int inv6 = fpow(6,MOD - 2);
x1 = Complex<3>(2,1);x2 = Complex<3>(2,MOD - 1);
c1 = Complex<3>(mul(3,inv6),inv6);c2 = Complex<3>(mul(3,inv6),MOD - inv6);
int ans = mul(invfac[k],fpow((r - l + 1) % MOD,MOD - 2));
r = r / 2;
if(l & 1) l = (l + 1) / 2;
else l = l / 2; Complex<3> res;
if(l <= r) {
for(int j = 1 ; j <= k ; ++j) {
Complex<3> s;
for(int h = 0 ; h <= j ; ++h) {
Complex<3> t = C(j,h) * fpow(c1,h) * fpow(c2,j - h),q = fpow(x1,h) * fpow(x2,j - h),p;
p = Query(q,r) - Query(q,l - 1);
s = s + t * p;
}
res = res + s * f[j];
}
}
ans = mul(ans,res.r);
out(ans);enter;
}
}
void Solve() {
read(l);read(r);read(k);
memset(f,0,sizeof(f));
f[1] = 1;
for(int i = 1 ; i < k ; ++i) {
for(int j = i + 1 ; j >= 1 ; --j) {
f[j] = inc(mul(MOD - i,f[j]),f[j - 1]);
}
}
if(m == 2) mequal2::Main();
else mequal3::Main();
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
int T;
read(T);read(m);
fac[0] = 1;
for(int i = 1 ; i <= 1000 ; ++i) fac[i] = mul(fac[i - 1],i);
invfac[1000] = fpow(fac[1000],MOD - 2);
for(int i = 999 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);
for(int i = 1 ; i <= T ; ++i) {
Solve();
}
}

【LOJ】#3090. 「BJOI2019」勘破神机的更多相关文章

  1. LOJ 3090 「BJOI2019」勘破神机——斯特林数+递推式求通项+扩域

    题目:https://loj.ac/problem/3090 题解:https://www.luogu.org/blog/rqy/solution-p5320 1.用斯特林数把下降幂化为普通的幂次求和 ...

  2. loj 3090 「BJOI2019」勘破神机 - 数学

    题目传送门 传送门 题目大意 设$F_{n}$表示用$1\times 2$的骨牌填$2\times n$的网格的方案数,设$G_{n}$$表示用$1\times 2$的骨牌填$3\times n$的网 ...

  3. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  4. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  5. [BJOI2019]勘破神机(斯特林数,数论)

    [BJOI2019]勘破神机(斯特林数,数论) 题面 洛谷 题解 先考虑\(m=2\)的情况. 显然方案数就是\(f_i=f_{i-1}+f_{i-2}\),即斐波那契数,虽然这里求出来是斐波那契的第 ...

  6. [BJOI2019]勘破神机

    [BJOI2019]勘破神机 推式子好题 m=2,斐波那契数列,$f_{n+1}$项 不妨$++l,++r$,直接求$f_n$ 求$\sum C(f_n,k)$,下降幂转化成阶乘幂,这样都是多项式了, ...

  7. LOJ 3089 「BJOI2019」奥术神杖——AC自动机DP+0/1分数规划

    题目:https://loj.ac/problem/3089 没想到把根号之类的求对数变成算数平均值.写了个只能得15分的暴力. #include<cstdio> #include< ...

  8. LOJ 3094 「BJOI2019」删数——角标偏移的线段树

    题目:https://loj.ac/problem/3094 弱化版是 AGC017C . 用线段树维护那个题里的序列即可. 对应关系大概是: 真实值的范围是 [ 1-m , n+m ] :考虑设偏移 ...

  9. LOJ 3093 「BJOI2019」光线——数学+思路

    题目:https://loj.ac/problem/3093 考虑经过种种反射,最终射下去的光线总和.往下的光线就是这个总和 * a[ i ] . 比如只有两层的话,设射到第二层的光线是 lst ,那 ...

随机推荐

  1. 图论小专题C

    3 负环及其应用 3.1 判定算法 判断负环只能用"边松弛"算法,也就是Bellman-Ford和SPFA算法.这两个算法都是\(O(NM)\)级别的.因为负环中一定存在一条负边, ...

  2. Appium基础教程

    目录 Appium教程 Appium简介 App自动化测试工具对比 Appium实现原理 环境搭建 Andorid介绍 基本架构 常见布局/视图 基本控件 控件常见属性 Adb介绍 Adb常用命令 A ...

  3. Java线程之创建线程

    翻译自:https://www.journaldev.com/1016/java-thread-example 进程 进程是一个自包含的执行环境,它可以被看成一个程序或应用程序.然而一个应用程序本身包 ...

  4. JavaWeb_(Spring框架)SpringAOP面向切面编程

    SpringAOP:面向切面编程(面向fifter编程) 通俗易懂术语:所有纵向重复的代码,我们提取成横向的代码 以下文章内容参考知乎:从0带你学习SpringAOP,彻底的理解AOP思想 传送门 1 ...

  5. MySQL| MySQL关键字和保留字

    MySQL 5.5 Keywords and Reserved Words The following list shows the keywords and reserved words in My ...

  6. golang精选100题带答案

    能力模型 级别 模型 初级 primary 熟悉基本语法,能够看懂代码的意图: 在他人指导下能够完成用户故事的开发,编写的代码符合CleanCode规范: 中级 intermediate 能够独立完成 ...

  7. L1-049 天梯赛座位分配 (20 分)

    L1-049 天梯赛座位分配 (20 分)(Java解法) 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所 ...

  8. LightGBM新特性总结

    LightGBM提出两种新方法:Gradient-based One-Side Sampling (GOSS) 和Exclusive Feature Bundling (EFB)(基于梯度的one-s ...

  9. Qt DLL总结【一】-链接库预备知识

    1.链接库概念 静态链接库和动态链接库介绍 我们可以创建一种文件里面包含了很多函数和变量的目标代码,链接的时候只要把这个文件指示给链接程序就自动地从文件中查找符合要求的函数和变量进行链接,整个查找过程 ...

  10. 自动化测试 | 好用的自动化测试工具Top 10

    欲善其事必先利其器,本文从软件测试人员痛点出发,介绍如何先从工具选择上取得优势,在有限的时间内完成工作.经常有人在公众号留言或是后台咨询,做自动化测试用哪个工具好,或是学哪门编程语言好呢? 这个时候总 ...