题目传送门

  传送门

题目大意

  设$F_{n}$表示用$1\times 2$的骨牌填$2\times n$的网格的方案数,设$G_{n}$$表示用$1\times 2$的骨牌填$3\times n$的网格的方案数.

  • 给定$l, r, k$,求$\frac{1}{r - l + 1}\sum_{i = l}^{r} \binom{F_{i}}{k}$.
  • 给定$l, r, k$,求$\frac{1}{r - l + 1}\sum_{i = l}^{r} \binom{G_{i}}{k}$.

  之前好像在loj / uoj群上问过求Fibonacci求立方和。sad。。。

  校内考的时候忘了求数列通项,sad。。。

  首先用Stirling数把组合数拆成通常幂。

  对于第一部分,直接用$Fibonacci$通项,由于$5$不是模$998244353$的二次剩余,所以把答案在运算中表示成$a + b\sqrt{5}$的形式。

  第$n$项的$k$次幂大概是$(a^n + b^n)^{K}$,这个不方便直接求和。用二项式定理展开就行了。

  对于第二部分。考察选手是否上过高考数学课(bushi

  显然当$2 \nmid n$时$G_{n} = 0$,现在考虑$G'_{n} = G_{2n}$。

  注意到最后只有这几种填法:

  所以有

$$
\begin{align}
G'_{n} &= 3G_{n - 1} + 2\sum_{i = 0}^{n - 2}G_{i} \\
&= 4G_{n - 1} - 3G_{n - 2} - 2\sum_{i = 0}^{n - 3} G_{i - 1} + 2\sum_{i =0}^{n - 2}G_i \\
&= 4G_{n - 1} - G_{n - 2}
\end{align}
$$

  用特征根法推通项(不会的话可以回教室了)。然后做完了。

  (我被Jode锤爆了。瑟瑟发抖.jpg)

Code

#include <bits/stdc++.h>
using namespace std;
typedef bool boolean;#define ll long longvoid exgcd(int a, int b, int& x, int& y) {if (!b) {x = 1, y = 0;} else {exgcd(b, a % b, y, x);y -= (a / b) * x;}
}int inv(int a, int n) {int x, y;exgcd(a, n, x, y);return (x < 0) ? (x + n) : (x);
}const int Mod = 998244353;template <const int Mod = :: Mod>
class Z {public:int v;Z() : v(0) {  }Z(int x) : v(x){   }Z(ll x) : v(x % Mod) { }friend Z operator + (const Z& a, const Z& b) {int x;return Z(((x = a.v + b.v) >= Mod) ? (x - Mod) : (x));}friend Z operator - (const Z& a, const Z& b) {int x;return Z(((x = a.v - b.v) < 0) ? (x + Mod) : (x));}friend Z operator * (const Z& a, const Z& b) {return Z(a.v * 1ll * b.v);}friend Z operator ~(const Z& a) {return inv(a.v, Mod);}friend Z operator - (const Z& a) {return Z(0) - a;}Z& operator += (Z b) {return *this = *this + b;}Z& operator -= (Z b) {return *this = *this - b;}Z& operator *= (Z b) {return *this = *this * b;}friend boolean operator == (const Z& a, const Z& b) {return a.v == b.v;}
};Z<> qpow(Z<> a, int p) {Z<> rt = Z<>(1), pa = a;for ( ; p; p >>= 1, pa = pa * pa) {if (p & 1) {rt = rt * pa;}}return rt;
}typedef Z<> Zi;template <const int I>
class ComplexTemp {public:Zi r, v;ComplexTemp() : r(0), v(0) {  }ComplexTemp(Zi r) : r(r), v(0) {   }ComplexTemp(Zi r, Zi v) : r(r), v(v) { }friend ComplexTemp operator + (const ComplexTemp& a, const ComplexTemp& b) {return ComplexTemp(a.r + b.r, a.v + b.v);}friend ComplexTemp operator - (const ComplexTemp& a, const ComplexTemp& b) {return ComplexTemp(a.r - b.r, a.v - b.v);}friend ComplexTemp operator - (const ComplexTemp& a, const int& b) {return ComplexTemp(a.r - b, a.v);           } friend ComplexTemp operator * (const ComplexTemp& a, const ComplexTemp& b) {return ComplexTemp(a.r * b.r + a.v * b.v * I, a.r * b.v + a.v * b.r);}friend ComplexTemp operator * (const ComplexTemp& a, const Zi& x) {return ComplexTemp(a.r * x, a.v * x);}friend ComplexTemp operator / (const ComplexTemp& a, const ComplexTemp& b) {ComplexTemp c = b.conj();return a * c * ~((b * c).r);}ComplexTemp conj() const {return ComplexTemp(r, -v);}boolean operator == (ComplexTemp b) {return r == b.r && v == b.v;}
};const int Kmx = 510;Zi s1[Kmx][Kmx];
Zi comb[Kmx][Kmx];
Zi fac[Kmx], _fac[Kmx];
void prepare(int n) {fac[0] = 1;for (int i = 1; i <= n; i++) {fac[i] = fac[i - 1] * i;}_fac[n] = ~fac[n];for (int i = n; i; i--) {_fac[i - 1] = _fac[i] * i;}s1[0][0] = 1;for (int i = 1; i <= n; i++) {s1[i][0] = 0, s1[i][i] = 1;for (int j = 1; j < i; j++) {s1[i][j] = s1[i - 1][j - 1] + s1[i - 1][j] * (i - 1);}}comb[0][0] = 1;for (int i = 1; i <= n; i++) {comb[i][0] = comb[i][i] = 1;for (int j = 1; j < i; j++) {comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];}}
}template <typename T>
T qpow(T a, ll p) {T rt = Zi(1), pa = a;for ( ; p; p >>= 1, pa = pa * pa) {if (p & 1) {rt = rt * pa;}}return rt;
}namespace subtask1 {typedef ComplexTemp<5> Complex;const Zi inv2 ((Mod + 1) >> 1);
const Complex q1 (inv2, inv2), q2 (inv2, -inv2);
Complex pwq1[Kmx], pwq2[Kmx], pwqq[Kmx][Kmx];Complex get_sum(int k1, int k2, ll n) {Complex x = pwq1[k1] * pwq2[k2];if (x == Zi(1))return Zi(n);return (pwqq[k1][k2] - 1) / (x - 1);
}inline void init() {pwq1[0] = pwq2[0] = Zi(1);for (int i = 1; i < Kmx; i++) {pwq1[i] = pwq1[i - 1] * q1;pwq2[i] = pwq2[i - 1] * q2;}
}Zi work(ll n, int K) {Complex coef = qpow(Complex(0, ~Zi(5)), K);Complex ret (0, 0);for (int k = 0; k <= K; k++) {
//      Complex tmp = get_sum(pwq1[k] * pwq2[K - k], n) * comb[K][k];Complex tmp = get_sum(k, K - k, n) * comb[K][k];if ((K - k) & 1) {ret = ret - tmp;} else {ret = ret + tmp;}}ret = ret * coef;assert(ret.v.v == 0);
//  cerr << n << " " << K << " " << ret.r.v << '\n';return ret.r;
}Zi solve(ll n, int K) {Zi ans = 0;Complex q1n = qpow(q1, n + 1);Complex q2n = qpow(q2, n + 1);pwqq[0][0] = Zi(1);for (int i = 0; i <= K; i++) {for (int j = (i == 0); i + j <= K; j++) {pwqq[i][j] = ((!i) ? (pwqq[i][j - 1] * q2n) : (pwqq[i - 1][j] * q1n));}}for (int i = 1; i <= K; i++) {Zi tmp = work(n, i) * s1[K][i] * _fac[K];if ((K - i) & 1) {ans -= tmp;} else {ans += tmp;}}return ans;
}void __main__(ll l, ll r, int K) {++l, ++r;Zi ans = solve(r, K) - solve(l - 1, K);ans = ans * ~Zi(r - l + 1);printf("%d\n", ans.v);
}}namespace subtask2 {typedef ComplexTemp<3> Complex;const Zi inv2 ((Mod + 1) >> 1);
const Zi inv3 ((Mod + 1) / 3);
const Zi inv6 = inv2 * inv3;
const Complex c1 (inv2, -inv6), c2 (inv2, inv6);
const Complex q1 (2, Mod - 1), q2 (2, 1);
Complex pwq1[Kmx], pwq2[Kmx], pwc1[Kmx], pwc2[Kmx];
Complex pwqq[Kmx][Kmx];Complex get_sum(int k1, int k2, ll n) {Complex x = pwq1[k1] * pwq2[k2];if (x == Zi(1))return Zi(n);return (pwqq[k1][k2] - 1) / (x - 1);
}inline void init() {pwq1[0] = pwq2[0] = pwc1[0] = pwc2[0] = Zi(1);for (int k = 1; k < Kmx; k++) {pwq1[k] = pwq1[k - 1] * q1;pwq2[k] = pwq2[k - 1] * q2;pwc1[k] = pwc1[k - 1] * c1;pwc2[k] = pwc2[k - 1] * c2;}
}Zi work(ll n, int K) {Complex ret (0, 0);for (int k = 0; k <= K; k++) {Complex tmp = get_sum(k, K - k, n) * comb[K][k];Complex b = pwc1[k] * pwc2[K - k];tmp = tmp * b;ret = ret + tmp;}assert(ret.v.v == 0);
//  cerr << n << " " << K << " " << ret.r.v << '\n';return ret.r;
}Zi solve(ll n, int K) {n >>= 1;Zi ans = 0;Complex q1n = qpow(q1, n + 1);Complex q2n = qpow(q2, n + 1);pwqq[0][0] = Zi(1);for (int i = 0; i <= K; i++) {for (int j = (i == 0); i + j <= K; j++) {pwqq[i][j] = ((!i) ? (pwqq[i][j - 1] * q2n) : (pwqq[i - 1][j] * q1n));}}for (int i = 1; i <= K; i++) {Zi tmp = work(n, i) * s1[K][i] * _fac[K];if ((K - i) & 1) {ans -= tmp;} else {ans += tmp;}}return ans;
}void __main__(ll l, ll r, int K) {Zi ans = solve(r, K) - solve(l - 1, K);ans = ans * ~Zi(r - l + 1);printf("%d\n", ans.v);
}}int Case, ___;
ll l, r;
int K;
int main() {prepare(502);scanf("%d%d", &Case, &___);if (___ == 3) {subtask2::init();} else {subtask1::init();}while (Case--) {scanf("%lld%lld%d", &l, &r, &K);if (___ == 2) {subtask1::__main__(l, r, K);} else {subtask2::__main__(l, r, K);}}return 0;
}

转载于:https://www.cnblogs.com/yyf0309/p/10779035.html

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」勘破神机

    LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...

  3. 「BJOI 2019」勘破神机

    传送门 problem 经过了一个月的艰苦尝试,你的研究团队破译了 "2""2""2" 型奥术宝石和 "3"" ...

  4. 【BJOI2019】勘破神机【数论】

    传送门(难得正经一回) 神题,思想值得学习. 首先明确题意: 两个子问题,一个2xN,一个3xN. 接下来对这个问题进行慢慢的推敲 解方案数 很明显,我们要先解决放置方案数的公式,才能做这个题. 对于 ...

  5. 【BJOI2019】勘破神机(下降幂转自然幂)(第一类斯特林数)(特征方程)

    传送门 题解: 完全自己推出来的第一道数学神题. 首先我们知道宽度为222的部分方案数是斐波那契数列. 设fnf_nfn​表示长度为nnn的时候方案数,题目要求的实际上是这个东西: ∑n=lr(fnk ...

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

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

  7. [BJOI2019]勘破神机

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

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

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

  9. 【luogu P5320】勘破神机(数学)(数列特征方程)(第一类斯特林数)

    勘破神机 题目链接:luogu P5320 题目大意 给你 l,r,kl,r,kl,r,k(其中 l,rl,rl,r 很大,k≤501k\leq 501k≤501),求: 1r−l+1∑i=lrCfi ...

最新文章

  1. php7 实战 新闻类,楼+之PHP7实战第1期
  2. 第六课.模型评估与模型选择
  3. Gartner 「RPA市场竞争格局」:中国厂商首次进入国际视野
  4. 后端调用python_【后端开发】python如何调用api接口
  5. Android Context getSystemService分析
  6. 训练softmax分类器实例_CS224N NLP with Deep Learning(四):Window分类器与神经网络
  7. 三维插值(MATLAB)——TriScatteredInterp/scatteredInterpolant函数
  8. homestead安装swoole扩展
  9. Android PDF阅读
  10. Xv6 Page Table
  11. Unity Shader学习记录第一章
  12. 魔窗--H5网页唤醒APP
  13. C语言键盘方向键的读入
  14. 服务器查看日志几种方式
  15. webRTC(十):webrtc 实现web端对端视频
  16. 计算机毕业设计Java夕阳红养老院系统(源码+系统+mysql数据库+Lw文档)
  17. Androdi平台camera的相关知识总结
  18. Android应用《撕开美女衣服》的实现过程及源代码
  19. 100集华为HCIE安全培训视频教材整理 | 双机热备(一)
  20. 可视频通话的软电话eyeBeam下载地址

热门文章

  1. 几何图形GeometricObject类
  2. 面试题01.05.一次编辑
  3. 病案首页计算机管理系统功能一般不包括,病案管理系统
  4. 21根火柴常胜将军c语言,常胜将军算法
  5. 300套PPT模板+实习僧20套精选简历+其他各种素材PPT模板(免费分享)
  6. 某计算机内存容量8GB,按字编址,每个字包括2字节,需要多少根地址线?
  7. java excel 单元格 斜线_JAVA POI EXCEl单元格内部分字符设置样式 HSSFRichTextString用法...
  8. Unity中Obi绳子设置
  9. 动态规划 - 切钢条 (python)
  10. 八条佛曰 66句震撼人心的禅语