[bzoj1965] 洗牌
题意:给你一副1010级别的扑克牌,一开始按1-n排列,然后每次重排,将原排列分成两份,取第二份的第一个为新排列的第一个,取第一份的第一个为新排列的第二个,依次类推,问你重排m次后,第l位上的牌是多少。
题解:
数论
发现规律:重排一次后,x的位置变为2*x\pmod{n+1}
然后设x为l位上的数字,有x*2^m{\equiv}l\pmod{n+1}
2在n+1下的逆元是n/2+1,则有x\equiv(n/2+1)^m*l\pmod{n+1}
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll gi() {
ll x=0,o=1; char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return o*x;
}
ll mul(ll x, ll y, ll p) {
ll ret=0;
while(y) {
if(y&1) (ret+=x)%=p;
(x+=x)%=p,y>>=1;
}
return ret;
}
ll qpow(ll x, ll y, ll p) {
ll ret=1;
while(y) {
if(y&1) ret=mul(ret,x,p)%p;
x=mul(x,x,p)%p,y>>=1;
}
return ret;
}
int main() {
ll n=gi(),m=gi(),l=gi();
ll inv=qpow(n/2+1,m,n+1);
printf("%lld\n", mul(inv,l,n+1));
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· .NET Core GC压缩(compact_phase)底层原理浅谈
· Winform-耗时操作导致界面渲染滞后
· Phi小模型开发教程:C#使用本地模型Phi视觉模型分析图像,实现图片分类、搜索等功能
· 语音处理 开源项目 EchoSharp