2019牛客暑期多校训练营(第五场) generator 1 (矩阵快速幂,10进制快速幂 / 指数循环节)

本文主要是介绍2019牛客暑期多校训练营(第五场) generator 1 (矩阵快速幂,10进制快速幂 / 指数循环节),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

题目链接:https://ac.nowcoder.com/acm/contest/885/B?&headNav=acm

思路:由于给你的指数很大,所以需要用十进制的快速幂(之前都没见过,算是长见识了)耗时1500ms

 

还有+1大佬独创的求指数循环节的方法  耗时36ms

 


//这是十进制快速幂
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5; 
struct node {ll a[2][2];
}; 
node mul (node a, node b, ll mod) {node ans;memset(ans.a, 0, sizeof(ans.a));for(int i = 0; i < 2; i++) {for(int j = 0; j < 2; j++) {for(int k = 0; k < 2; k++) {ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;}}}return ans;
} 
char s[maxn]; 
int main()
{ll x, y, a, b, mod;node ans, tmp, aa;scanf("%lld %lld %lld %lld", &x, &y, &a, &b);scanf("%s", s);scanf("%lld", &mod);int t = strlen(s);aa.a[0][0] = a;    aa.a[0][1] = 1;    aa.a[1][0] = b;    aa.a[1][1] = 0;ans.a[0][0] = 1;   ans.a[1][1] = 1;   ans.a[0][1] = 0;   ans.a[1][0] = 0;for(int le = t - 1; le >= 0; le--) {int b = s[le] - '0';tmp.a[0][0] = 1; tmp.a[1][1] = 1;  tmp.a[0][1] = 0; tmp.a[1][0] = 0;for(int i = 0; i < b ; ++i)  ans = mul(ans, aa, mod);for(int i = 0; i < 10 ; ++i)  tmp = mul(tmp, aa, mod);aa = tmp;}   printf("%lld\n", (ans.a[1][1] * x + ans.a[0][1] * y) % mod );return 0;
}

 

 

//求指数循环节

//求指数循环节
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
struct node {ll a[2][2];
};int cnt,pri[100000+10];
void init(){ll limit;for(int i = 2; i <= 100000; i++){if(!pri[i]) pri[cnt++] = i;for(int j = 0; j < cnt; j++){limit = 1ll * i * pri[j];if(limit > 100000) break;pri[limit] = 1;if(i%pri[j] == 0) break;}}
}
ll solve(ll x){ll ans1 = 1, ans2=1, xx = x;for(int i = 0; i < cnt; i++){if(1ll * pri[i] * pri[i] > x) break;if(x % pri[i] == 0){ans1 *= (pri[i] - 1) * (pri[i] + 1);ans2 *= pri[i];while(x % pri[i] == 0) x /= pri[i];}}if(x>1){ans1 *= (x - 1) * (x + 1);ans2 *= x;}return xx / ans2 * ans1;
}node mul (node a, node b, ll mod) {node ans;memset(ans.a, 0, sizeof(ans.a));for(int i = 0; i < 2; i++) {for(int j = 0; j < 2; j++) {for(int k = 0; k < 2; k++) {ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;}}}return ans;
}
node ksm(node a, ll b, ll mod) {node ans;ans.a[0][0] = 1;ans.a[1][1] = 1;ans.a[0][1] = 0;ans.a[1][0] = 0;while(b) {if(b & 1) ans = mul(ans, a, mod);a = mul(a, a, mod);b >>= 1;}return ans;
}
char s[maxn];
ll ksc(ll x, ll y, ll z){x %= z;y %= z;ll ans = 0;while(y){if(y & 1){ans += x;if(ans >= z) ans -= z;}x <<= 1;if(x >= z) x -= z;y >>= 1;}return ans;
}
int main()
{ll x, y, a, b, mod, m, n;node ans, aa;scanf("%lld %lld %lld %lld", &x, &y, &a, &b);scanf("%s", s);scanf("%lld", &mod);int t = strlen(s);init();m = solve(mod), n = 0;for(int i = 0; i < t; i++) {n = ksc(n , 10 ,m) ;n = n + s[i] -'0';if(n >= m) n -= m;}aa.a[0][0] = a;aa.a[0][1] = 1;aa.a[1][0] = b;aa.a[1][1] = 0;ans = ksm(aa, n, mod);printf("%lld\n", (ans.a[1][1] * x + ans.a[0][1] * y) % mod );return 0;
}

 

这篇关于2019牛客暑期多校训练营(第五场) generator 1 (矩阵快速幂,10进制快速幂 / 指数循环节)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/853540

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

usaco 1.2 Palindromic Squares(进制转化)

考察进制转化 注意一些细节就可以了 直接上代码: /*ID: who jayLANG: C++TASK: palsquare*/#include<stdio.h>int x[20],xlen,y[20],ylen,B;void change(int n){int m;m=n;xlen=0;while(m){x[++xlen]=m%B;m/=B;}m=n*n;ylen=0;whi

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数