【题目大意】

f(i)=((Af(i-1)+B)/(Cf(i-1)+D)) mod P。

给出f(0), A, B, C, D, P, n,求f(n)。

多组数据T<=1e4

n<=1e18, P <= 1e9, |f(0)|,|A|,|B|,|C|,|D| <= 1e9

保证任何时候存在逆元。

【题解】

首先我们有一种O(TP)的做法:找循环节。

考场上因为数据原因是可以AC的。。

# include <map>
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + ; # define RG register
# define ST static int A, B, C, D, mod, lm, rm;
ll f[], n;
map<int, int> mp; inline ll exgcd(ll a, ll b, ll &x, ll &y) {
if(b == ) {
x = ;
y = ;
return a;
}
exgcd(b, a%b, x, y);
ll t = x;
x = y;
y = t - (a/b)*y;
} inline ll getinv(ll n) {
ll x, y;
exgcd(n, (ll)mod, x, y);
x = (x%mod + mod) % mod;
return x;
} inline void sol() {
scanf("%lld%d%d%d%d%lld%d", &f[], &A, &B, &C, &D, &n, &mod);
A = (A+mod)%mod; B = (B+mod)%mod;
C = (C+mod)%mod; D = (D+mod)%mod;
mp.clear(); lm = rm = -; mp[f[]] = ;
for (int i=; i<=mod; ++i) {
f[i] = (A*f[i-] + B) % mod * getinv(C*f[i-] + D) % mod;
if(mp.find(f[i]) != mp.end()) {
lm = mp[f[i]], rm = i;
break;
}
mp[f[i]] = i;
}
// printf("%d %d\n", lm, rm);
assert(lm != - && rm != -);
if(n <= lm) printf("%lld\n", f[n]);
else printf("%lld\n", f[(n-lm)%(rm-lm)+lm]);
} int main() {
freopen("exercise.in", "r", stdin);
freopen("exercise.out", "w", stdout);
int T; cin >> T;
while(T--) sol();
return ;
}

标准做法是

f(i)=((Af(i-1)+B)/(Cf(i-1)+D))

f(i-1)=((Af(i-2)+B)/(Cf(i-2)+D))

那么

f(i)=((A^2+BC)f(i-2)+(AB+BD))//((AC+CD)f(i-2)+(CD+D^2))

相当于两个2*2的矩阵乘在一起。

那么矩乘即可。

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + ; # define RG register
# define ST static int f0, A, B, C, D, mod, ans;
ll n; inline ll exgcd(ll a, ll b, ll &x, ll &y) {
if(b == ) {
x = ;
y = ;
return a;
}
exgcd(b, a%b, x, y);
ll t = x;
x = y;
y = t - (a/b)*y;
} inline int getinv(ll n) {
ll x, y;
exgcd(n, (ll)mod, x, y);
x = (x%mod + mod) % mod;
return x;
} struct matrix {
int a[][], n;
inline void set() {memset(a, , sizeof a);}
friend matrix operator * (matrix a, matrix b) {
matrix c; c.set();
for (int i=; i<=; ++i)
for (int j=; j<=; ++j)
for (int k=; k<=; ++k)
(c.a[i][j] += 1ll * a.a[i][k] * b.a[k][j] % mod) %= mod;
return c;
}
friend matrix operator ^ (matrix a, ll b) {
matrix c; c.set(); c.a[][] = c.a[][] = ;
while(b) {
if(b&) c=c*a;
a=a*a;
b >>= ;
}
return c;
}
}E; inline void sol() {
scanf("%d%d%d%d%d%lld%d", &f0, &A, &B, &C, &D, &n, &mod);
A = (A+mod) % mod; B = (B+mod) % mod; C = (C+mod) % mod; D = (D+mod) % mod;
E.set(); E.a[][] = A, E.a[][] = B, E.a[][] = C, E.a[][] = D;
E = E^n;
A = E.a[][], B = E.a[][], C = E.a[][], D = E.a[][];
ans = getinv((ll)C * f0 + D);
ans = 1ll * ans * (1ll * A * f0 % mod + B) % mod;
printf("%d\n", ans);
} int main() {
freopen("exercise.in", "r", stdin);
freopen("exercise.out", "w", stdout);
int T; cin >> T;
while(T--) sol();
return ;
}

校内训练0602 习题exercise的更多相关文章

  1. [4.14校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi....        很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...

  2. [2017.4.7校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...

  3. [3.24校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...

  4. 19_04_19校内训练[Game]

    题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...

  5. 19_04_02校内训练[deadline]

    题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...

  6. 平面图转对偶图&19_03_21校内训练 [Everfeel]

    对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...

  7. fzyzojP3979 -- [校内训练20180914]魔法方阵

    原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...

  8. fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试

    题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...

  9. fzyzojP3372 -- [校内训练20171124]博弈问题

    对于每个点都要答案 还是异或 trie树合并石锤了 朴素枚举是O(n^2*17)的 怎么办呢? 我们发现合并的时候,一些部分的trie的子树还是不变的 改变的部分也就是合并的复杂度可以接受 鉴于大部分 ...

随机推荐

  1. PHP开发搭建环境二:开发工具PhpStorm安装、激活以及配置

    关于php的开发工具很多,目前市面上最好用最强大的莫过于PhpStorm这款开发神器了,但是鉴于很多开发者朋友在网站上下载的PhpStorm开发工具不能用,或者使用起来很不方便,笔者把最好用的下载地址 ...

  2. 数据分析处理库Pandas——merge操作

    有一列列名相同值也相同 有两列列名相同值也相同 按其中一列合并 按两列合并 有一列列名相同值也相同,有一列列名相同值不相同,按两列合并 列名相同值不相同的行删掉 保留所有行 保留所有行并显示合并后该值 ...

  3. bedtools

  4. Oozie 安装及 examples app 的使用

    参考文档 一.Building OOzie 特别注意的是修改Pom.xml文件中的版本与本机中安装的版本相同 二. install Oozie 1.为 hadoop 添加 Oozie 的代理用户,添加 ...

  5. echo shell commands as they are executed

    http://stackoverflow.com/questions/2853803/in-a-shell-script-echo-shell-commands-as-they-are-execute ...

  6. centos使用--排查服务是否可用

    端口与服务的关系 一台拥有IP地址的主机可以提供许多服务,比如Web服务.FTP服务.SMTP服务等,这些服务完全通过1个IP地址来实现.那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因 ...

  7. 【NOIP 2017 提高组】列队

    题目 有一个 \(n\times m\) 的方阵,每次出来一个人后向左看齐,向前看齐,询问每次出来的人的编号. \(n\le 3\times 10^5\) 分析 我们考虑离队本质上只有两种操作: 删除 ...

  8. 如何创造财富?硅谷创业之父 Paul Graham 《黑客与画家》思维导图

    先送上亚马逊传送门:<黑客与画家>:硅谷创业之父 Paul Graham 文集 再送上一个思维导图: 下载大图:http://caifujianghu.com/article/ruhe-c ...

  9. windows 下开发的 .netCore MVC 部署到 Linux(Mint)

    这两天在公司跟同事偶然聊到 .netCore,说到一些趋势什么的.但是说来说去自己也没试过在Linux 机子上部署过,所以就试一下. 尝试之前也在网上看了一些文章,包括 Linux 上.netCore ...

  10. Python 3基础教程7-if语句

    前面文章介绍的循环语句,这里开始介绍控制语句.直接看下面的demo.py例子 # 这里介绍 if语句 x = 5y = 8z = 4s = 5 if x < y: print('x is les ...