首页 > 其他分享 >SHUFFLE 洗牌

SHUFFLE 洗牌

时间:2024-03-29 17:35:11浏览次数:21  
标签:ch SHUFFLE 扑克牌 int res 洗牌 define mod

[AHOI2005] 洗牌

传送门

题目描述

为了表彰小联为 Samuel 星球的探险所做出的贡献,小联被邀请参加 Samuel 星球近距离载人探险活动。

由于 Samuel 星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联提议用扑克牌打发长途旅行中的无聊时间。玩了几局之后,大家觉得单纯玩扑克牌对于像他们这样的高智商人才来说太简单了。有人提出了扑克牌的一种新的玩法。

对于扑克牌的一次洗牌是这样定义的,将一叠 \(N\)(\(N\)为偶数)张扑克牌平均分成上下两叠,取下面一叠的第一张作为新的一叠的第一张,然后取上面一叠的第一张作为新的一叠的第二张,再取下面一叠的第二张作为新的一叠的第三张……如此交替直到所有的牌取完。

如果对一叠 \(6\) 张的扑克牌 \({1,2,3,4,5,6}\),进行一次洗牌的过程如下图所示:

从图中可以看出经过一次洗牌,序列 \(1,2,3,4,5,6\) 变为 \(4,1,5,2,6,3\)。当然,再对得到的序列进行一次洗牌,又会变为 \(2,4,6,1,3,5\)。

游戏是这样的,如果给定长度为 \(N\) 的一叠扑克牌,并且牌面大小从 \(1\) 开始连续增加到 \(N\)(不考虑花色),对这样的一叠扑克牌,进行 \(M\) 次洗牌。最先说出经过洗牌后的扑克牌序列中第 \(L\) 张扑克牌的牌面大小是多少的科学家得胜。小联想赢取游戏的胜利,你能帮助他吗?

输入格式

输入文件中有三个用空格间隔的整数,分别表示 \(N,M,L\)。

(其中 \(1\le N\le 10^{10},0 \le M\le 10^{10}\),且 \(N\) 为偶数)。

输出格式

单行输出指定的扑克牌的牌面大小。

样例 #1

样例输入 #1

6 2 3

样例输出 #1

6

提示

\(0 < N \leq 10^{10}\),\(0 \leq M \leq 10^{10}\),且 \(N\) 为偶数。

分析

由题,易得
每次洗牌后第 \(i\) 张牌会转移到第 \(2*i \%(n+1)\) 的位置上

即在\(mod(n+1)\)意义下,\(i\) 和 \(2i\) 是同余的

\[i * 2^{m} \equiv l \qquad(mod (n+1)) \]

再稍微导亿导

\[2^{m} * i + (n+1) * k = l \]

\[2^{m} * \frac{i}{l} + (n+1) * \frac{k}{l}=1 \]

之后利用exgcd求出\(\frac{i}{l}\)解再乘上l就可以了
\(\\\)

\(\\\)
吗?

千辛万苦打出代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f
#define INF 1e9+100
#define mst(a,b) memset(a,b,sizeof(a))
#define re register
#define Elaina 0
const int N = 10000100;

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}

int t,n,m,k,mod,ans;
int s[N],p[N],l[N];
bool vis[N];

int exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1;
		y=0;
		return a;
	}
	int res=exgcd(b,a%b,x,y);
	int t=x;
	x=y;
	y=t-a/b*y;
	return res;
}

int qpow(int a, int b){
	int res=1;
	while(b){
		if(b&1){
			res=res*a%(n+1);
		}
		a=a*a%(n+1);
		b>>=1;
	}
	return res;
}

main(){
	n=read(),m=read(),k=read();
	int p=qpow(2,m);
	int xx,yy;
	exgcd(p,n+1,xx,yy);
	while(xx<0){
		xx+=n+1;
	}
	return printf("%lld",xx*k%(n+1)),Elaina;
}


WA了

为啥呢

简单推算可知

longlong他爆掉了

那咋办呢

__int128

__int128固然是可以的 但他太低端

有个东西 他叫“龟速乘”

即牺牲时间而保证你的longlong不会boom一下爆掉~

他长这样↓ 和快速幂几乎是别无二致

int mul(int a,int b,int mod){
	int res=0;
	while(b){
		if(b&1){
			res=(res+a)%mod;
		}
		a=(a+a)%mod;
		b>>=1;
	}
	return res%mod;
}

code

Elaina's code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f
#define INF 1e9+100
#define mst(a,b) memset(a,b,sizeof(a))
#define re register
#define Elaina 0
const int N = 10000100;

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}

int t,n,m,k,mod,ans;
//int ;
//bool ;

int exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1;
		y=0;
		return a;
	}
	int res=exgcd(b,a%b,x,y);
//	x^=y^=x^=y;
//	y-=a/b*x;
	int t=x;
	x=y;
	y=t-a/b*y;
	return res;
}

int mul(int a,int b,int mod){
	int res=0;
	while(b){
		if(b&1){
			res=(res+a)%mod;
		}
		a=(a+a)%mod;
		b>>=1;
	}
	return res%mod;
}

int qpow(int a,int b,int mod){
	int res=1;
	while(b){
		if(b&1){
			res=mul(res,a,mod);
		}
		a=mul(a,a,mod);
		b>>=1;
	}
	return res%mod;
}

main(){
	n=read(),m=read(),k=read();
	int p=qpow(2,m,n+1);
	int xx,yy;
	exgcd(p,n+1,xx,yy);
	while(xx<0){
		xx+=n+1;
	}
	printf("%lld",mul(xx,k,n+1));
	return Elaina;
}

都看到这了,真的不点个赞吗(>ω<*)

标签:ch,SHUFFLE,扑克牌,int,res,洗牌,define,mod
From: https://www.cnblogs.com/Elaina-0/p/18104281

相关文章

  • [AHOI2005] SHUFFLE 洗牌
    这是一道逆元的模板题。看到题,首先找下规律:首先想到是否存在循环,即经过多次洗牌后回到原状态的情况,但手玩了几组以后发现有循环但没有规律,只能知道循环节长度小于等于\(n\),显然会\(TLE\);所以对于一些循环节较长的数据很容易被卡掉(比如这组:900000000011)代码转载自@Ish......
  • CF1392H ZS Shuffles Cards 题解
    题目传送门前置知识概率DP解法设\(f_{i}\)表示有\(i\)张数字牌没进入\(S\),即\(S\)中只有\(n-i\)张数字牌时的期望轮数,有\(f_{i}=\frac{i}{i+m}f_{i-1}+\frac{m}{i+m}(f_{i}+1)\),解得\(f_{i}=f_{i-1}+\frac{m}{i}\),边界为\(f_{0}=1\)。由于每一张数字牌在joke......
  • YoloV5、ShuffleNetV2、YoloV5-Lite网络概述
    前言前段时间需要在树莓派上部署一个深度学习环境,先试了YoloV5,fs基本才0.3,远远达不到要求,于是就尝试了一下轻量化网络,试过mobileNet系列+YoloV4,fps有所提升,大概能达到0.9左右,但还是比较慢,于是就发现了YoloV5-Lite这个轻量化网络,极大地加速了fps,基本能达到3左右,因此详细了解了......
  • 21. 实现洗牌逻辑
    洗牌方法洗牌的时候,会把弃牌堆清除,牌堆中的每张牌都会和随机的牌进行交换一共有两个地方会进行洗牌操作,第一个是初始化牌堆的时候第二个是抽牌堆为空的时候项目相关代码代码仓库:https://gitee.com/nbda1121440/DreamOfTheKingdom.git标签:20240305_1905......
  • net8 随机数类Random GetItems() 、Shuffle()方法
    1、在8中对随机数类Random提供了GetItems()方法,可以根据指定的数量在提供的一个集合中随机抽取数据项生成一个新的集合:ReadOnlySpan<string>colors=new[]{"Red","Green","Blue","Black"};string[]t1=Random.Shared.GetItems(colors,10);Console.WriteLine(......
  • 轻量化CNN网络 - ShuffleNet
    1.ShuffleNetV1论文:ShuffleNet:AnExtremelyEfficientConvolutionalNeuralNetworkforMobileDevices网址:https://arxiv.org/abs/1707.01083提出了``ChannelShuffle`的思想,在ShuffleUnit中全是GConv和DWConv。GConv虽然能够减少参数与计算量,但GConv中不同组之间信......
  • spark中的shuffle
    在Spark中,Shuffle是一个核心概念和步骤,它是数据分发的过程,需要消耗大量的资源和时间。Shuffle的主要功能是将分布在各个节点上的同一类数据汇集到某一个节点上进行计算,此过程有助于提高整体性能和吞吐量。同时,Shuffle作为连接Map阶段和Reduce阶段的桥梁,其性能受到磁盘和网......
  • Shuffle与Stage划分
    一:Shuffle   在宽依赖关系中,RDD会根据每条记录的key进行不同分区的数据聚集,数据聚集的过程称为Shuffle。例如,对一个RDD进行reduceByKey()操作,RDD中相同key的所有记录将进行聚合,而key相同的所有记录可能不在同一个分区中,甚至不在同一个节点上,但是该操作必须将这些记录聚集到......
  • 【题解】AtCoder agc065_a Shuffle and mod K
    传送门:https://atcoder.jp/contests/agc065/tasks/agc065_a 为了方便理解,我们把要求的东西乘一个$-1$,再把答案序列倒过来;也就是说,我们现在要求$min_{A'}^{A'为A的排列}(\sum_{i=1}^{N-1}((A_{i+1}-A_{i})$$mod$$K))$比较显然的是,如果我们确定了答案序列的第一个数是多......
  • [Codeforces] CF1733C Parity Shuffle Sorting
    题面翻译给定一个长度为\(n\)的数组,你可以对它进行不超过\(n\)次操作。对于每次操作:选择两个下标\(l,r\),满足\(1\leql<r\leqn\);若\(a_l+a_r\)为奇数,将\(a_r\)赋值为\(a_l\),否则将\(a_l\)赋值为\(a_r\)。求一种方案,使得操作后的数组单调不减(即\(a_1\leq......