洛谷P2054 [AHOI2005]洗牌(扩展欧几里德)

洛谷题目传送门

来个正常的有证明的题解

我们不好来表示某时刻某一个位置是哪一张牌,但我们可以表示某时刻某一张牌在哪个位置。

设数列{aij}表示i号牌经过j次洗牌后的位置,我们试着来递推一下

首先,如果此刻牌在上面一叠,显然aij+1=2aij

接着,如果这张牌在下面一叠,那么aij+1=2(aijn2)1=2aij(n+1),应该也很好推出来

写在一起,观察一下

aij+1={2aij ,aijn22aij(n+1),aij>n2

诶,两个式子都有一个系数2呢!那我们可不可以把它看成模n+1意义下的结果呢?

于是可以进一步得到aij2mi(modn+1)i就是ai0

题目已经知道了aij,来求i,不就是一个线性同余不定方程么?exgcd搞一下就好啦!因为gcd(2m,n+1)=1,所以根本不用像青蛙的约会那样麻烦。

看楼上大佬用异或写swap?!第一次见的蒟蒻表示只能Orz。然后蒟蒻就把exgcd这个函数成功压缩到了一行。。。。。。

#include<cstdio>
#define LL long long
LL n,m,l,x=1,y;
LL qpow(LL b,LL k){//快速幂求2^m
	LL a=1;
	while(k){
		if(k&1)a*=b,a%=n+1;
		b*=b,b%=n+1;
		k>>=1;
	}
	return a;
}
void exgcd(LL a,LL b){//一行exgcd233
	if(b)exgcd(b,a%b),(y^=x^=y^=x)-=a/b*x;
}
int main(){
	scanf("%lld%lld%lld",&n,&m,&l);
	exgcd(qpow(2,m),n+1);
	printf("%lld\n",(l*x%(n+1)+n+1)%(n+1));//注意化成最小正整数
	return 0;
}
posted @   Flash_Hu  阅读(233)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示
剑桥
17:14发布
剑桥
17:14发布
5°
西风
7级
空气质量
相对湿度
34%
今天
多云
-3°/5°
周六
-1°/3°
周日
-2°/7°