校内训练0602 习题exercise
【题目大意】
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的更多相关文章
- [4.14校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi.... 很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...
- [2017.4.7校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...
- [3.24校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...
- 19_04_19校内训练[Game]
题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...
- 19_04_02校内训练[deadline]
题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...
- 平面图转对偶图&19_03_21校内训练 [Everfeel]
对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...
- fzyzojP3979 -- [校内训练20180914]魔法方阵
原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...
- fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试
题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...
- fzyzojP3372 -- [校内训练20171124]博弈问题
对于每个点都要答案 还是异或 trie树合并石锤了 朴素枚举是O(n^2*17)的 怎么办呢? 我们发现合并的时候,一些部分的trie的子树还是不变的 改变的部分也就是合并的复杂度可以接受 鉴于大部分 ...
随机推荐
- B-树 动机与结构
Ps.我们遵循从感性到理性的认知顺序来逐步探索B-树的奥秘,之前经常说的value这里用key(关键码)指代,因为可能存的是字符串,说是value就不合适了. (多图预警!!!建议在WI-FI下观看) ...
- Android 中运行时权限获取联系人信息 Demo
代码比较简单... AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <m ...
- SharpCompress的压缩文件解压和文件夹压缩
1.前言 最近做一个功能需要用到对压缩文件的解压,就找到了这个SharpCompress不错,还能解压rar的文件.但是网上的资料和我拿到的SharpCompress.dll的方法有些出入,所以我就自 ...
- 如何让button保持点击状态
http://blog.csdn.net/u010957508/article/details/38385207 他的原理就是在代码里面: view.setSelected(true); 而其他的: ...
- 分布式缓存技术memcached学习系列(一)——linux环境下编译memcahed
安装依赖工具 [root@localhost upload]# yum install gcc make cmake autoconf libtool 下载并上传文件 memcached 依 ...
- 《Cracking the Coding Interview》——第17章:普通题——题目1
2014-04-28 21:45 题目:就地交换两个数,不使用额外的变量. 解法:没说是整数,我姑且先当整数处理吧.就地交换可以用加法.乘法.异或完成,其中乘法和加法都存在溢出问题.三种方法都不能处理 ...
- [网站公告]1月10日1:00-7:00阿里云RDS维护会造成30秒闪断
大家好! 阿里云将于1月10号1:00-7:00(今天夜里)对杭州机房部分RDS实例所在的物理主机做维护操作,维护期间部分RDS实例会有1-2次闪断,每次闪断时间在30秒以内. 我们使用的RDS实例将 ...
- Canvas 图形组合方式
/** * 图形组合 */ function initDemo5() { var canvas = document.getElementById("demo5"); if (!c ...
- 新建git仓库--留
1.git config 配置配置息,查看配置信息
- c语言版贪吃蛇小游戏
编译环境:windows 7 64位 编译工具:codeblocks 13.12 备注:未使用graphics.h 声明:个人原创,未经允许,禁止转载!!! 数据结构:双向链表 1.程序未使用grap ...