数论练习二之BSGS算法——随机数生成器,Matrix,Lunar New Year and a Recursive Sequence,Fermat‘s Last Theorem

[SDOI2013] 随机数生成器

description

solution

肯定是非常想找一个通项公式来表示第nnn个数的
在这里插入图片描述

依据形式,考虑化成等比数列

xi+1+k=a(xi+k)=a⋅xi+b+t⇒k=ba−1x_{i+1}+k=a(x_i+k)=a·x_i+b+t\Rightarrow k=\frac{b}{a-1}xi+1+k=a(xi+k)=axi+b+tk=a1b

⇒xi+ba−1=ai−1(x1+ba−1)(modp)⇒ai−1≡(xi+b⋅(a−1)−1)⋅(x1+b⋅(a−1)−1)−1(modp)\Rightarrow x_i+\frac{b}{a-1}=a^{i-1}(x_1+\frac{b}{a-1})\pmod p\Rightarrow a^{i-1}\equiv (x_i+b·(a-1)^{-1})·(x_1+b·(a-1)^{-1})^{-1}\pmod pxi+a1b=ai1(x1+a1b)(modp)ai1(xi+b(a1)1)(x1+b(a1)1)1(modp)

xix_ixi就是题目中的ttt,所以式子只有ai−1a^{i-1}ai1这个指数未知,bsgs求解最小指数(ppp是质数)

但要先特判a=0/1a=0/1a=0/1两种情况,显然此情况下等比数列式子是不成立的

  • a=0

    xi=bx_i=bxi=b

  • a=1

    xi≡x1+b(i−1)(modp)⇔(t−x1)b−1≡i−1(modp)x_i\equiv x_1+b(i-1)\pmod p\Leftrightarrow (t-x_1)b^{-1}\equiv i-1\pmod pxix1+b(i1)(modp)(tx1)b1i1(modp)

code

#include <map>
#include <cmath>
#include <cstdio>
using namespace std;
#define int long long
map < int, int > mp;int bsgs( int a, int r, int p ) {if( a % p == 0 ) return -1;mp.clear();int m = ceil( sqrt( p * 1.0 ) );int IS = 1;for( int i = 1;i <= m;i ++ ) {IS = IS * a % p;mp[IS * r % p] = i;}int SI = 1;for( int i = 1;i <= m;i ++ ) {SI = SI * IS % p;if( mp.count( SI ) ) return i * m - mp[SI] + 1;}return -1;
}int T, p, a, b, x1, t;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % p;x = x * x % p;y >>= 1;}return ans;
}int inv( int x ) {return qkpow( x, p - 2 );
}signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld %lld %lld %lld", &p, &a, &b, &x1, &t );if( x1 == t ) {printf( "1\n" );continue;}if( a == 0 ) {if( x1 == t ) printf( "1\n" );else if( b == t ) printf( "2\n" );else printf( "-1\n" );continue;}if( a == 1 ) {if( b == 0 ) printf( "-1\n" );else printf( "%lld\n", ( ( t - x1 ) % p + p ) % p * inv( b ) % p + 1 );continue;}printf( "%lld\n", bsgs( a, ( t + b * inv( a - 1 ) % p ) * inv( x1 + b * inv( a - 1 ) % p ) % p, p ) );}	return 0;
}

[BZOJ4128]Matrix

description

solution

因为保证了AAA矩阵有逆,所以可以选择求矩阵的逆

但其实还是选择两边同乘矩阵要好一些

BSGS模板,有优质代码是写了非常迅速的hash

但是偶直接map里面塞矩阵,重载一下map的小于等于比较挺不戳的!
在这里插入图片描述

code

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int n, mod;
struct matrix {int c[71][71];void clear() {memset( c, 0, sizeof( c ) );}matrix() {clear();}void init() {for( int i = 1;i <= n;i ++ ) {for( int j = 1;j <= n;j ++ )c[i][j] = 0;c[i][i] = 1;}}matrix operator * ( const matrix &t ) const {matrix ans;for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )for( int k = 1;k <= n;k ++ )ans.c[i][j] = ( ans.c[i][j] + c[i][k] * t.c[k][j] ) % mod;return ans;}friend bool operator == ( const matrix &s, const matrix &t ) {for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )if( s.c[i][j] ^ t.c[i][j] ) return 0;return 1;}friend bool operator < ( const matrix &s, const matrix &t ) {for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )if( s.c[i][j] ^ t.c[i][j] ) return s.c[i][j] < t.c[i][j];return 0;}
}A, B, g, h;
map < matrix, int > mp;int main() {scanf( "%d %d", &n, &mod );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )scanf( "%d", &A.c[i][j] );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )scanf( "%d", &B.c[i][j] );int m = ceil( sqrt( mod * 1.0 ) );g.init();for( int i = 1;i <= m;i ++ ) {g = g * A;h = g * B;mp[h] = i;}h.init();for( int i = 1;i <= m;i ++ ) {h = h * g;if( mp.count( h ) ) return ! printf( "%d\n", i * m - mp[h] );}return 0;
}

CF1106F Lunar New Year and a Recursive Sequence

problem

solution

fi=∏j=1kfi−jbj(modp)f_{i}=\prod_{j=1}^kf_{i-j}^{b_j}\pmod pfi=j=1kfijbj(modp)

ppp是非常特殊的质数,其原根为333,可以用原根改写上式,令3gi=fi3^{g_i}=f_i3gi=fi

gi=∑j=1kgi−j⋅bj(modφ(p))g_i=\sum_{j=1}^kg_{i-j}·b_j\pmod {\varphi(p)}gi=j=1kgijbj(modφ(p))

此时的ggg可以用矩阵加速,初始化fi=0(i<k),fk=1f_i=0(i<k),f_k=1fi=0(i<k),fk=1,转移n−kn-knk次变成[fn−k+1,...,fn][f_{n-k+1},...,f_n][fnk+1,...,fn]
[hi−k+1,...,hi⏟k]×[00...0bk10...0bk−101...0bk−2...............00...0b200...1b1]=[hi+k+2,...,hi+1⏟k]\begin{bmatrix} \underbrace{h_{i-k+1},...,h_i}_{k} \end{bmatrix}\times \begin{bmatrix} 0&0&...&0&b_k\\ 1&0&...&0&b_{k-1}\\ 0&1&...&0&b_{k-2}\\ ...&...&...&...&...\\ 0&0&...&0&b_2\\ 0&0&...&1&b_1 \end{bmatrix}= \begin{bmatrix} \underbrace{h_{i+k+2},...,h_{i+1}}_{k} \end{bmatrix} [khik+1,...,hi]×010...00001...00..................000...01bkbk1bk2...b2b1=[khi+k+2,...,hi+1]
同时,有fkt≡fn(modp),3gk=fkf_k^t\equiv f_n\pmod p,3^{g_k}=f_kfktfn(modp),3gk=fk,这里的ttt矩等于加速矩阵自乘后的hkh_khk

fkT=3gk⋅T≡fn=3gn(modp)f_k^T=3^{g_k·T}\equiv f_n=3^{g_n}\pmod pfkT=3gkTfn=3gn(modp)

对于3gn≡fn(modp)3^{g_n}\equiv f_n\pmod p3gnfn(modp)gng_ngn未知,用BSGS求得

对于指数用exgcd计算,gk×t≡gn(modp−1)⇔t×gk−(p−1)×y=gng_k\times t\equiv g_n\pmod {p-1}\Leftrightarrow t\times g_k-(p-1)\times y=g_ngk×tgn(modp1)t×gk(p1)×y=gn

未知数为gk,yg_k,ygk,y,求出后fk=3gkf_k=3^{g_k}fk=3gk

code

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define int long long
#define mod 998244353
struct matrix {int n, m;int c[101][101];matrix() {memset( c, 0, sizeof( c ) );}matrix operator * ( matrix &t ) const {matrix ans;ans.n = n, ans.m = t.m;for( int i = 1;i <= n;i ++ )for( int j = 1;j <= t.m;j ++ )for( int k = 1;k <= m;k ++ )ans.c[i][j] = ( ans.c[i][j] + c[i][k] * t.c[k][j] ) % ( mod - 1 );return ans;}
}h, t;matrix qkpow( matrix x, int y ) {matrix ans;ans.n = ans.m = x.n;for( int i = 1;i <= ans.n;i ++ )ans.c[i][i] = 1;while( y ) {if( y & 1 ) ans = ans * x;x = x * x;y >>= 1;}return ans;
}map < int, int > mp;int bsgs( int a, int r ) {int m = ceil( sqrt( mod * 1.0 ) );int IS = 1;for( int i = 1;i <= m;i ++ ) {IS = IS * a % mod;mp[IS * r % mod] = i;}int MS = 1;for( int i = 1;i <= m;i ++ ) {MS = MS * IS % mod;if( mp.count( MS ) )return i * m - mp[MS];}return -1;
}int exgcd( int a, int b, int &x, int &y ) {if( ! b ) {x = 1, y = 0;return a;}else {int d = exgcd( b, a % b, y, x );y -= a / b * x;return d;}
}int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}signed main() {int k, n, fn;scanf( "%lld", &k );h.n = h.m = t.m = k, t.n = t.c[1][k] = 1;for( int i = 2;i <= k;i ++ )h.c[i][i - 1] = 1;for( int i = k;i;i -- )scanf( "%lld", &h.c[i][k] );scanf( "%lld %lld", &n, &fn );h = qkpow( h, n - k );t = t * h;int g = bsgs( 3, fn );int x, y, d = exgcd( t.c[1][k], mod - 1, x, y );if( g % d ) return ! printf( "-1\n" );else {x = ( x * ( g / d ) % ( mod - 1 ) + ( mod - 1 ) ) % ( mod - 1 );printf( "%lld\n", qkpow( 3, x ) );}return 0;
}

Fermat’s Last Theorem

description

solution

找出ppp的原根ggg,令x=ga,y=gb,z=gcx=g^a,y=g^b,z=g^cx=ga,y=gb,z=gc
gan+gbn≡gcn(modp)g^{an}+g^{bn}\equiv g^{cn}\pmod pgan+gbngcn(modp)
r=gn⇒ra+rb≡rc(modp)r=g^n\Rightarrow r^a+r^b\equiv r^c\pmod pr=gnra+rbrc(modp)
假设a≤ba\le bab

  • a≤c⇒1+rb−a≡rc−a(modp)a\le c\Rightarrow 1+r^{b-a}\equiv r^{c-a}\pmod pac1+rbarca(modp)
  • a>c⇒ra−c+rb−a≡1(modp)a>c\Rightarrow r^{a-c}+r^{b-a}\equiv 1\pmod pa>crac+rba1(modp)

枚举rkr^krk,出现循环的时候就break
出现1+rk1≡rk2/rk1+rk2≡1(modp)1+r^{k_1}\equiv r^{k_2}/r^{k_1}+r^{k_2}\equiv 1\pmod p1+rk1rk2/rk1+rk21(modp)就是有解了

code

#include <cstdio>
#define int long long
#define maxn 1000005
int d[maxn], vis[maxn], mi[maxn];int qkpow( int x, int y, int mod ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}int root( int p ) {int cnt = 0, phi = p - 1;for( int i = 2;i * i <= phi;i ++ )if( phi % i == 0 ) {d[++ cnt] = i;if( i * i != phi ) d[++ cnt] = phi / i;}for( int g = 1, i;;g ++ ) {for( i = 1;i <= cnt;i ++ )if( qkpow( g, d[i], p ) == 1 )break;if( i > cnt ) return g;}
}signed main() {int T, n, p;scanf( "%lld", &T );for( int Case = 1;Case <= T;Case ++ ) {scanf( "%lld %lld", &n, &p );int g = root( p ), r = qkpow( g, n, p );int t = 1, x = -1, y, z;for( int i = 0;i < p;i ++ ) {if( i ) t = t * r % p;if( vis[t] == Case ) break;vis[t] = Case, mi[t] = i;int MS = 1 + t;if( MS >= p ) MS = 0;int IS = 1 - t + p;if( IS >= p ) IS = 0;if( vis[MS] == Case ) {x = 1, y = qkpow( g, i, p ), z = qkpow( g, mi[MS], p );break;}if( vis[IS] == Case ) {x = qkpow( g, i, p ), y = qkpow( g, mi[IS], p ), z = 1;break;}}if( ~ x ) printf( "%lld %lld %lld\n", x, y, z );else printf( "-1\n" );}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317329.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NetCore下模拟和使用Modbus工业通信协议

Tips&#xff1a;1、目前NetCore下与Modbus通信的框架主要选择了 Modbus.Net https://github.com/parallelbgls/Modbus.Net2、modbus是常用的工业通信协议&#xff0c;在软件调试时可以通过modbus pollslave模拟通信通过达到调试目的&#xff0c;下图是我使用软件1&#xff09…

C - Rencontre Gym - 102798C

C - Rencontre Gym - 102798C 参考题解&#xff1a; 参考一 参考二 题意&#xff1a; 有一棵树&#xff0c;树上的点分为三种&#xff0c;&#xff08;一个点可以为多种&#xff09;&#xff0c;现在分别在三种点中随机选一点a&#xff0c;b&#xff0c;c&#xff0c;然后找到…

API标准化成为技术团队面临的最大挑战

调查表明&#xff0c;API 标准化成为了技术团队面临的最大挑战。SmartBear 发布了 2019 年 API 状态报告“The State of API 2019”&#xff0c;此报告旨在为 API 行业建立关于软件团队在 2019 年规划、设计、开发、测试、记录和监控 API 的方法、实践和工具的基准。此次调查有…

线性代数五之高斯消元——[SDOI2010]外星千足虫,[HNOI2013]游走,[HNOI2011]XOR和路径,[hdu 4035]Maze

多类型高斯消元杂题[SDOI2010]外星千足虫descriptionsolutioncode[HNOI2013]游走descriptionsolutioncode[HNOI2011]XOR和路径descriptionsolutioncodeMaze(树上高斯消元)problemsolutioncode[SDOI2010]外星千足虫 description solution 高斯消元的模板题 虽然感觉问了个最…

Ocelot 资源汇总

前言最近一两年.NET Core的关注度持续上升, 微服务及云原生应用开发上采用.NET Core也越来越多&#xff0c;Ocelot 作为.NET Core平台下一款开源的API 网关开发库越来越得到社区的认可&#xff0c;应用到生产中的案例也有好几百了。春节抽空整理了现有网上公开的Ocelot相关的资…

[TJOI2017]城市(未解决)

[TJOI2017]城市 题意&#xff1a; 一棵树&#xff0c;现在要求你将一条边改变他的位置&#xff0c;&#xff08;即改变左右所连接的端点&#xff0c;权值不变&#xff09;&#xff0c;修改后任意两点相互可达&#xff0c;且使得两个点之间的最大交通费用最小 题解: 有O(n^2…

数论三之组合数学Ⅰ-Max-Min Sums,Binomial Coefficient is Fun,Strivore,Bubble Sort,放棋子,LOJ6671,Iroha and a Grid

组合计数我最爱Max-Min SumsdescriptionsolutioncodeBinomial Coefficient is FundescriptionsolutioncodeStrivoredescriptionsolutioncodeBubble Sortdescriptionsolutioncode[HAOI2016]放棋子descriptionsolutioncodeEntropyIncreaser 与 MinecraftdescriptionsolutioncodeD…

语言之争与读书有感

移动互联网无处不在的今天&#xff0c;不同的学习方式让我们受益颇多。有人喜欢通过手机阅读各类技术专家的公众号分享&#xff1b;有人喜欢通过逛逛不同的博客&#xff0c;来了解当前时下的技术&#xff1b;也有人喜欢通过社区的形式&#xff0c;跟优秀的导师们一起梳理和发展…

CF566E-Restoring Map【bitset】

正题 题目链接:https://www.luogu.com.cn/problem/CF566E 题目大意 有一棵树&#xff0c;但是你不知道它的形态。你现在只知道距离每个点距离不超过222的点集&#xff0c;但是你不知道每个点集是对应哪个点的。 现在要你求这棵树。 2≤n≤10002\leq n\leq 10002≤n≤1000 解…

所有人都可以是开发人员——《Office 365开发入门指南》视频教程即将上市

今天是春节假期的最后一天&#xff0c;在这里给全国的朋友们拜个晚年&#xff0c;祝大家身体健康&#xff0c;晚年幸福啊。这个春节大家过的怎么样啊&#xff0c;我自己是在老家过的年&#xff0c;家乡的年味还是比较浓的&#xff0c;也再次感谢朋友圈的大家给我看了各地的风光…

数论三之排列组合Ⅱ——Virus Tree 2,RGB Coloring,123 Triangle,排列计数,排队,卡农

丝且人一口Virus Tree 2descriptionsolutioncodeRGB Coloringdescriptionsolutioncode123 Triangledescriptionsolutioncode[SDOI2016]排列计数descriptionsolutioncode[HNOI2012]排队descriptionsolutioncode[HNOI2011]卡农descriptionsolutioncodeVirus Tree 2 description …

.NET Core开发日志——OData

简述OData&#xff0c;即Open Data Protocol&#xff0c;是由微软在2007年推出的一款开放协议&#xff0c;旨在通过简单、标准的方式创建和使用查询式及交互式RESTful API。类库在.NET Core中想要使用OData功能的话需要添加Microsoft.AspNetCore.OData包。dotnet add package M…

ML.NET 0.10特性简介

IDataView被单独作为一个类库包IDataView组件为表格式数据提供了非常高效的处理方式&#xff0c;尤其是用于机器学习和高级分析应用。它被设计为可以高效地处理高维数据和大型数据集。并且也适合处理属于更大的分布式数据集中的单个数据区块结点。在ML.NET 0.10中&#xff0c;I…

数论五之容斥——硬币购物,Gerald and Giant Chess,幸运数字,Sky Full of Stars,已经没有什么好害怕的了

容斥的神[HAOI2008]硬币购物problemsolutioncodeCF559C Gerald and Giant Chessproblemsolutioncode[SCOI2010]幸运数字problemsolutioncodeCF997C Sky Full of Starsproblemsolutioncode已经没有什么好害怕的了problemsolutioncode[JLOI2015]骗我呢problemsolutioncode容斥要么…

NET Core微服务之路:基于Ocelot的API网关Relay实现--RPC篇

前言我们都知道&#xff0c;API网关是工作在应用层上网关程序&#xff0c;为何要这样设计呢&#xff0c;而不是将网关程序直接工作在传输层、或者网络层等等更底层的环境呢&#xff1f;让我们先来简单的了解一下TCP/IP的五层模型。&#xff08;图片出自http://www.cnblogs.com/…

Windows 10《描图》应用现已开源

点击上方蓝字关注“汪宇杰博客”《描图》是我最早的Windows 10应用&#xff0c;发布至今已3年多&#xff0c;积累了全球数百万用户&#xff0c;广受好评。现已开源。这款应用为不少小朋友带去了欢乐&#xff0c;体验绘画的乐趣&#xff0c;也帮助过专业用户复刻数百幅古代绘画。…

数论六之计算几何干货——计算几何模板解释全集 及 模板检验训练场

文章目录点和向量及运算直线和线段求解点到直线的距离/点在直线上求解点到线段的距离/点在线段上求解两条线段是否相交求解两直线的交点多边形求解多边形面积求解多边形重心求解判断定点与多边形的位置关系凸包graham扫描法graham扫描法加强版圆求解圆与直线的交点求解圆与圆的…

P3959 [NOIP2017 提高组] 宝藏

P3959 [NOIP2017 提高组] 宝藏 题意: 额题意不好说&#xff0c;就是n个点m个边&#xff0c;选定一个点为根节点&#xff0c;构造一个最小生成树&#xff0c;边的权值为该该边起点到根节点之间的点的数量K&#xff08;不含根节点&#xff09; * 道路长度 1<n<12 0<m&…

如何在ASP.NET Core程序启动时运行异步任务(3)

原文&#xff1a;Running async tasks on app startup in ASP.NET Core (Part 3)作者&#xff1a;Andrew Lock译者&#xff1a;Lamond Lu之前我写了两篇有关在ASP.NET Core中运行异步任务的博文&#xff0c;本篇博文是对之前两篇博文中演示示例和实现方法的简短跟进。你可以通过…

【NET CORE微服务一条龙应用】应用部署

简介本章主要介绍https://github.com/q315523275/FamilyBucket上微服务一条龙应用&#xff0c;在实际使用中的应用部署&#xff0c;以原始方式部署非docker部署应用主要包括&#xff1a;1、网关应用部署2、授权认证应用部署3、配置中心查询服务端应用部署4、综合管理应用部署5、…