要点

  • 998244353的原根g = 3,意味着对于任意$$1 <= x,y<p$$$$x\neq\ y$$$$gx%p\neq gy%p$$因此可以有构造序列\(q(a)与a一一对应,g^{q(a)}\%p=a\)。那么对应到这道题上,因为\(f_i\)是%p的,所以构造\(h_i\)序列,使得$$g{h_i}%p=f_i=\prod_{j=1}{k}(f_{i-j}){b_j}%p=g{\sum_{j=1}^k{h_{i-j}\times\ b_j}}%p$$$$\because 原根的唯一对应性质且g^{p-1}%p=1$$$$\therefore h_i\equiv \sum_{j=1}^kh_{i-j}\times b_j(mod\ p-1)$$
  • 以上就是本题全部关键了,接下来就是数论复习内容了。
  • 首先看到这个熟悉的式子想到我们可以\(\%(p-1)\)意义下矩阵快速幂求解,往常是给前面的项求第n项,这次是有\(h_n\)求\(h_k\)。
  • 其中\(h_n\)的求法是BSGS算法
  • 矩阵快速幂以后,因为题面说初始除了\(f_k\)以外都是1,所以\(h_{1…k-1}\)都是0,故而有$$h_n\equiv Matrix[0][0]\times h_k(mod\ p-1)$$
  • 这就变成了\(ah_x\equiv c(\%b)\),变形为\(ax+by=c\)即可用扩展欧几里得求解,若有解,用快速幂求得\(f_k\),否则输出-1.
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
const int p = 998244353, g = 3;
int K, b[101], n, fn, hn, hk; struct Matrix {
int n;
int v[101][101]; Matrix(int n) { memset(v, 0, sizeof v); this->n = n; } friend Matrix operator * (Matrix A, Matrix B) {
int n = A.n;
Matrix ret(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++) {
ret.v[i][j] = ((ll)ret.v[i][j] + (ll)A.v[i][k] * B.v[k][j] % (p - 1)) % (p - 1);
}
return ret;
} friend Matrix operator ^ (Matrix A, int k) {
int n = A.n;
Matrix ret(n);
for (int i = 0; i < n; i++)
ret.v[i][i] = 1;
for (; k; k >>= 1) {
if (k & 1) ret = ret * A;
A = A * A;
}
return ret;
}
}; namespace BSGS {
const int maxm = 1e5 + 1000;
int hash_table[maxm], val[maxm]; int ksm(int a, int b, int mod) {
int res = 1;
for (; b; b >>= 1) {
if (b & 1) res = (ll)res * a % mod;
a = (ll)a * a % mod;
}
return res;
} int find(int n) {
int id = n % maxm;
while (hash_table[id] >= 0 && hash_table[id] != n)
id = (id + 1) % maxm;
return id;
} int bsgs(int a, int b, int p) {
a %= p, b %= p;
if (!a) return b ? -1 : 1;
memset(hash_table, -1, sizeof hash_table); int m = sqrt(p) + 1;
int now = b;
hash_table[now % maxm] = now;
val[now % maxm] = 0;
for (int i = 1; i <= m; i++) {
now = (ll)now * a % p;
int pos = find(now);
hash_table[pos] = now;
val[pos] = i;
} int t = ksm(a, m, p);
now = 1;
for (int i = 1; i <= m; i++) {
now = (ll)now * t % p;
int pos = find(now);
if (hash_table[pos] >= 0) {
return i * m - val[pos];
}
} return -1;
}
} namespace EXGCD {
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1, y = 0;
return a;
}
ll q = exgcd(b, a % b, y, x);
y -= a / b * x;
return q;
} int solve(int a, int b, int c) {//ax = c (% b)求x的解
if (!c) return 0;
int q = gcd(a, b);
if (c % q) return -1; a /= q, b /= q, c /= q;
ll ans, __;
exgcd((ll)a, (ll)b, ans, __);
ans = (ans * c % b + b) % b;
return ans;
}
} int main() {
scanf("%d", &K);
for (int i = 0; i < K; i++)
scanf("%d", &b[i]), b[i] %= p - 1;
scanf("%d%d", &n, &fn); hn = BSGS::bsgs(g, fn, p);
Matrix A(K);
for (int i = 0; i < K; i++)
A.v[0][i] = b[i];
for (int j = 1; j < K; j++)
A.v[j][j - 1] = 1;
A = A ^ (n - K);
hk = EXGCD::solve(A.v[0][0], p - 1, hn); if (hk >= 0) {
printf("%d\n", BSGS::ksm(g, hk, p));
} else {
printf("-1\n");
}
return 0;
}

Codeforces 1106F(数论)的更多相关文章

  1. Codeforces 1106F Lunar New Year and a Recursive Sequence | BSGS/exgcd/矩阵乘法

    我诈尸啦! 高三退役选手好不容易抛弃天利和金考卷打场CF,结果打得和shi一样--还因为queue太长而unrated了!一个学期不敲代码实在是忘干净了-- 没分该没分,考题还是要订正的 =v= 欢迎 ...

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

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

  3. CodeForces 300C --数论

    A - A Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  4. CodeForces 359D (数论+二分+ST算法)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47319 题目大意:给定一个序列,要求确定一个子序列,①使得该子序 ...

  5. Codeforces 264B 数论+DP

    题目链接:http://codeforces.com/problemset/problem/264/B 代码: #include<cstdio> #include<iostream& ...

  6. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem F (Codeforces 831F) - 数论 - 暴力

    题目传送门 传送门I 传送门II 传送门III 题目大意 求一个满足$d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil - \sum ...

  7. CodeForces 1202F(数论,整除分块)

    题目 CodeForces 1213G 做法 假设有\(P\)个完整的循环块,假设此时答案为\(K\)(实际答案可能有多种),即每块完整块长度为\(K\),则\(P=\left \lfloor \fr ...

  8. Vasya and Beautiful Arrays CodeForces - 354C (数论,枚举)

    Vasya and Beautiful Arrays CodeForces - 354C Vasya's got a birthday coming up and his mom decided to ...

  9. Neko does Maths CodeForces - 1152C 数论欧几里得

    Neko does MathsCodeForces - 1152C 题目大意:给两个正整数a,b,找到一个非负整数k使得,a+k和b+k的最小公倍数最小,如果有多个k使得最小公倍数最小的话,输出最小的 ...

随机推荐

  1. Appium基础——需要知道的

      Appium使用平台厂商提供的自动化框架: 1.ios 苹果的UIAutomation 2.android google的UIAutomator Appium底层使用厂商提供的自动化框架,就不需要 ...

  2. LR添加Windows和Linux压力机实战

    添加Windows和Linux压力机实战 既然Controller是LoadRunner的“心脏”,那么压力产生也必然是它发起的,通过压力机来对被测系统产生压力.一般压力机分为Windows和Linu ...

  3. 【应用】SVG动态 时钟

    没有做秒针,只做了分针和时针,5分钟以后来看应该可以看到效果╮(╯-╰)╭ <!DOCTYPE html> <html> <head> <title>& ...

  4. .NET CORE2.0后台管理系统(一)配置API

    一:引用关系图 要写一个项目首先离不开的就是一个清晰的流程图,当然我这里很简单. 上诉完成后打开api下的Startup.cs文件,因为我是配置好了所在我直接上传代码然后介绍一下: using Sys ...

  5. Relocation POJ-2923

    题目链接 题目意思: 有 n 个货物,并且知道了每个货物的重量,每次用载重量分别为c1,c2的火车装载,问最少需要运送多少次可以将货物运完. 分析:本题可以用二进制枚举所有不冲突的方案,再来dp 一下 ...

  6. CISCO-从路由器上下载IOS

    准备工作:一台装有TFTP服务器的PC,一台带有IOS的路由器,并用网线连接上 设置路由器接口和计算机网卡的IP地址在同一网段,并且互相能ping通. 1,安装Cisco TFTP Server 2, ...

  7. 51Nod - 1821:最优集合 (求第一个不能被表示为多个数的和的数)(不错的动脑题)

    一个集合S的优美值定义为:最大的x,满足对于任意i∈1,x1,x,都存在一个S的子集S',使得S'中元素之和为i. 给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个数k,要求选择 ...

  8. 为Xen虚拟机扩容根文件系统(LVM)

    ===== 为Xen虚拟机扩容根文件系统(LVM) ===== 1. 增加1个4G的映像文件 # dd if=/dev/zero of=data.img bs=4k seek=1024k count= ...

  9. HDOJ-2047

    阿牛的EOF牛肉串 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  10. 09.客户端集成IdentityServer

    09.客户端集成IdentityServer 新建API的项目 dotnet new webapi --name ClientCredentialApi 在我们上一节课的代码IdentityServe ...