我诈尸啦!

高三退役选手好不容易抛弃天利和金考卷打场CF,结果打得和shi一样……还因为queue太长而unrated了!一个学期不敲代码实在是忘干净了……

没分该没分,考题还是要订正的 =v= 欢迎阅读本题解!

P.S. 这几个算法我是一个也想不起来了 TAT

题目链接

Codeforces 1106F Lunar New Year and a Recursive Sequence 新年和递推数列

题意描述

某数列\(\{f_i\}\)递推公式:$$f_i = (\prod_{j=1}kf_{i-j}{b_j}) \bmod p$$

其中\(b\)是已知的长度为\(k\)的数列,\(p = 998244353\),\(f_1 = f_2 = ... = f_{k-1} = 1\),\(f_k\)未知。

给出两个数\(n, m\),构造一个\(f_k\)使得\(f_n = m\),无解输出-1。

\(k \le 100, n \le 10^9\)

题解

数论!真令人头秃!

首先这个数据范围让人想到什么?矩阵乘法!

矩阵乘法想推这个全是乘法和乘方的递推数列咋办?取对数!离散对数!

于是这道题关键的两个考点就被你发现啦!

(然而我太菜了,并不能发现 = =)

什么是离散对数?

众所周知(众==学过NTT的人等),这个喜闻乐见的模数\(p = 998244353\)有个原根\(g=3\),\(g^i(0\le i < P - 1)\)和\(1\le x < P\)一一对应。那么类比我们学过的对数,称这个\(i\)为\(x\)的离散对数。

令数列\(h_i\)为\(f_i\)的离散对数。

那么有递推式:$$h_i = (\sum_{j=1}^kb_j\cdot h_{i-j}) \bmod (p - 1)$$

其中\(h_1 = h_2 = ... = h_{k-1} = 0\)。注意模数变成了\(p - 1\)(费马小定理)。

这个就可以用矩阵加速了!如果我们把\(h_k\)设为1带进去,求得\(h_n = c\),那么有\(h_n = c \cdot h_k \bmod (p - 1)\);

\(h_n\)即为\(m\)的离散对数,用BSGS可求;

exgcd解刚才这个同余方程即可得到\(h_k\);

\(f_k = g^{h_k}\),快速幂即可得到\(f_k\)。

如果exgcd发现没有解的话就输出-1。

是不是思路非常清晰啊~

代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cassert>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 102, P = 998244353, P2 = 998244352, G = 3;
int K;
ll b[N], n, m, C; namespace BSGS {
const int S = 32000, M = 2000000;
int cnt = 0, adj[M + 5], nxt[S + 5];
ll key[S + 5], val[S + 5];
void insert(ll K, ll V){
int p = K % M;
key[++cnt] = K;
val[cnt] = V;
nxt[cnt] = adj[p];
adj[p] = cnt;
}
ll search(ll K){
for(int u = adj[K % M]; u; u = nxt[u])
if(key[u] == K) return val[u];
return -1;
}
void init(){
ll sum = 1;
for(int i = 1; i <= S; i++)
sum = sum * G % P;
ll tot = 1;
for(int i = 1; (i - 1) * S < P - 1; i++)
tot = tot * sum % P, insert(tot, i * S);
}
ll log(ll x){
ll sum = 1, ret;
for(int i = 1; i <= S; i++){
sum = sum * G % P;
ret = search(sum * x % P);
if(~ret && ret < P - 1) return ret - i;
}
assert(0);
return -1;
}
} struct matrix {
ll g[N][N];
matrix(){
memset(g, 0, sizeof(g));
}
matrix(int x){
memset(g, 0, sizeof(g));
for(int i = 1; i <= K; i++)
g[i][i] = 1;
}
matrix operator * (const matrix &b){
matrix c;
for(int i = 1; i <= K; i++)
for(int j = 1; j <= K; j++)
for(int k = 1; k <= K; k++)
c.g[i][j] = (c.g[i][j] + g[i][k] * b.g[k][j]) % P2;
return c;
}
}; ll qpow(ll a, ll x){
ll ret = 1;
while(x){
if(x & 1) ret = ret * a % P;
a = a * a % P;
x >>= 1;
}
return ret;
}
matrix qpow(matrix a, ll x){
matrix ret(1);
while(x){
if(x & 1) ret = ret * a;
a = a * a;
x >>= 1;
}
return ret;
}
ll calcC(){
matrix ret, op;
ret.g[K][1] = 1;
for(int i = 1; i < K; i++)
op.g[i][i + 1] = 1;
for(int i = 1; i <= K; i++)
op.g[K][i] = b[K - i + 1];
ret = qpow(op, n - K) * ret;
return ret.g[K][1];
}
void exgcd(ll a, ll b, ll &g, ll &x, ll &y){
if(!b) return (void)(x = 1, y = 0, g = a);
exgcd(b, a % b, g, y, x);
y -= x * (a / b);
}
ll solve(ll A, ll B){ //Ax % P2 == B, solve x
ll a = A, b = P2, g, x, y;
exgcd(a, b, g, x, y);
if(B % g) return -1;
x *= B / g, y *= B / g;
ll t = b / g;
x = (x % t + t) % t;
return x;
} int main(){ BSGS::init();
read(K);
for(int i = 1; i <= K; i++) read(b[i]);
read(n), read(m);
C = calcC();
m = BSGS::log(m);
ll ans = solve(C, m);
if(ans == -1) puts("-1");
else write(qpow(G, ans)), enter; return 0;
}

Codeforces 1106F Lunar New Year and a Recursive Sequence | BSGS/exgcd/矩阵乘法的更多相关文章

  1. Codeforces 1106F Lunar New Year and a Recursive Sequence (数学、线性代数、线性递推、数论、BSGS、扩展欧几里得算法)

    哎呀大水题..我写了一个多小时..好没救啊.. 数论板子X合一? 注意: 本文中变量名称区分大小写. 题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}b_i ...

  2. @codeforces - 1106F@ Lunar New Year and a Recursive Sequence

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义递推数列 f: (1)f[1] = f[2] = ... f ...

  3. CF1106F Lunar New Year and a Recursive Sequence 原根、矩阵快速幂、BSGS

    传送门 好久没写数论题了写一次调了1h 首先发现递推式是一个乘方的形式,线性递推和矩阵快速幂似乎都做不了,那么是否能够把乘方运算变成加法运算和乘法运算呢? 使用原根!学过\(NTT\)的都知道\(99 ...

  4. CF1106F Lunar New Year and a Recursive Sequence

    题目链接:CF1106F Lunar New Year and a Recursive Sequence 大意:已知\(f_1,f_2,\cdots,f_{k-1}\)和\(b_1,b_2,\cdot ...

  5. HDU - 5950 Recursive sequence(二项式+矩阵合并+矩阵快速幂)

    Recursive sequence Farmer John likes to play mathematics games with his N cows. Recently, they are a ...

  6. Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...

  7. CF1106F Lunar New Year and a Recursive Sequence 线性递推 + k次剩余

    已知\(f_i = \prod \limits_{j = 1}^k f_{i - j}^{b_j}\;mod\;998244353\),并且\(f_1, f_2, ..., f_{k - 1} = 1 ...

  8. CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)

    题面 传送门 前置芝士 \(BSGS\) 什么?你不会\(BSGS\)?百度啊 原根 对于素数\(p\)和自然数\(a\),如果满足\(a^x\equiv 1\pmod{p}\)的最小的\(x\)为\ ...

  9. CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&&bsgs

    题意 设 $$f_i = \left\{\begin{matrix}1 , \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  i < k\\ ...

随机推荐

  1. electron 开发实时加载

    第一个方式 cnpm install electron-reload --save-dev cnpm install electron-prebuilt --save-dev require('ele ...

  2. ML.NET 示例:开篇

    写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...

  3. WPF没落了吗?

    从08年开始一直到现在,碰到所有的项目,我个人经手的,都用wpf开发. wpf应该说一直没有火过,一直平平淡淡. 个人为什么一直执着用wpf,开始使用是因公司项目,做了两年wpf开发,后来换工作一直搜 ...

  4. 自从硬派网倒闭后,就没有什么好看的IT硬件网站了

    RT

  5. split-brain 脑裂问题(Keepalived)

    脑裂(split-brain)指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏.对于无状 ...

  6. Gerrit上分支操作记录(创建分支、删除分支)

    Git分支对于一个项目的代码管理而言,是十分重要的!许多久用git的朋友可能已经掌握的很牢固了,但对于一些初涉git的童鞋来说,可能还不是很熟悉.在此,我将自己的一些操作经历做一梳理,希望能帮助到有用 ...

  7. 12.9 Daily Scrum

    在一些实现上,开发人员提出了意见,经过讨论后,我们决定取消“推荐餐厅”的功能,增加了“菜谱分类”的功能. 同时更新了相关人员的任务.   Today's Task Tomorrow's Task 丁辛 ...

  8. 用软件工程分析开源项目octave的移植

    在本科的时候学习了软件工程,报考了信息系统项目管理师的考试,,虽然没有过,但是其实还是学了一些相关项目管理方面的知识,,9大管理,,当年应该能背出来,,, 1 项目整体管理 2 项目范围管理 3 项目 ...

  9. 阅读<构建之法>13、14、15、16、17章

    13章 这么多测试为什么不能整理出一个包括所有功能的测试呢?看着那么多测试都感觉奇怪了. 14章 怎样才能体现一个测试人员的工作价值呢?这样的判断又是否会太独断了? 15章 在时间上,会不会因不同功能 ...

  10. SMBv1 is not installed by default in Windows 10 Fall Creators Update 2017 and Windows Server, Semi-annual Channel

    windows 10 rs3 release enable SMBv1 windows 10 rs3 release file sharing https://support.microsoft.co ...