题目大意

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

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

如果给定长度为N的一叠扑克牌,并且牌面大小从1开始连续增加到N(不考虑花色),对这样的一叠扑克牌,进行M次洗牌。说出经过洗牌后的扑克牌序列中第L张扑克牌的牌面大小是多少。

思路

我们看看一张位于位置p扑克牌洗一次后的位置p'在哪里。若p<=N/2,这张扑克牌就到了第p对牌中的第2张,位置为p*2;若p>N/2,这张扑克牌就到了第p-N/2对牌中的第一张,故p'=(p-N/2)*2-1=p*2-(N+1)。因为p<=N/2时p*2%(N+1)=p*2,所以综上所述,p'=p*2%(N+1)。洗m次,即令运算*2%(N+1)进行m次,2便乘了m次,模了m遍N+1与只模一次的效果是相同的。综上所述,洗m次后牌移动到了位置p*2^m%(N+1)。现在给出最终的位置l,那么就是让我们解同余方程x*2^m≡l(mod N+1)。利用快速幂求2^m,然后解方程模板代入即可。

#include <cstdio>
#include <cstring>
using namespace std; #define ll long long ll Mult(ll a, ll b, ll p)
{
ll ans = 0;
while (b)
{
if (b & 1)
ans = (ans + a) % p;
a = (a+a)%p;
b >>= 1;
}
return ans;
} ll Power(ll a, ll n, ll p)
{
ll ans = 1;
while (n)
{
if (n & 1)
ans = Mult(ans, a, p);
a = Mult(a, a, p);
n >>= 1;
}
return ans;
} ll Exgcd(ll a, ll b, ll &x, ll &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
ll d = Exgcd(b, a%b, x, y);
ll tx = x;
x = y;
y = tx - (a / b) * y;
return d;
} ll Gcd(ll a, ll b)
{
return b ? Gcd(b, a%b) : a;
} ll Eq(ll a, ll b, ll m)
{
ll gcd = Gcd(a, m);
if (b%gcd)
return -1;
ll x, y;
Exgcd(a, m, x, y);
x = x * b / gcd;
ll p = m / gcd;
return (x%p+p) % p;
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
ll n, m, l;
scanf("%lld%lld%lld", &n, &m, &l);
printf("%lld\n", Eq(Power(2, m, n + 1), l, n+1));
return 0;
}

  

luogu2054 洗牌 同余方程的更多相关文章

  1. P2054 [AHOI2005]洗牌

    P2054 [AHOI2005]洗牌 题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度 ...

  2. 洛谷——P2054 [AHOI2005]洗牌(扩展欧几里得,逆元)

    P2054 [AHOI2005]洗牌 扩展欧拉定理求逆元 $1 2 3 4 5 6$$4 1 5 2 6 3$$2 4 6 1 3 5$$1 2 3 4 5 6$ 手推一下样例,你就会发现是有规律的: ...

  3. [LeetCode] Shuffle an Array 数组洗牌

    Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...

  4. 洗牌算法Fisher_Yates原理

    1.算法 http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 简单的原理如下图所示: 2.原理 总结下,洗牌算法Fisher_Yates ...

  5. C# 洗牌算法

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精   C#洗牌算法如下: class Program { ...

  6. [转]完美洗牌(Perfect Shuffle)问题

    [转]原博文地址:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.09.md ...

  7. PAT自测_打印沙漏、素数对猜想、数组元素循环右移、数字加倍重排、机器洗牌

    -自测1. 打印沙漏() 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号 ...

  8. Js实现简单的洗牌

    基础篇 洗牌采用的是,每一张牌,与后面随机一张牌来交换位置. 扑克牌采用编码制(如,0代表红桃A,依次类推)为了编码方便,扑克牌不含大小王,故52张. 一.扑克牌的了解 扑克(英文:Poker) 一副 ...

  9. Java集合List模拟“洗牌”操作

    Collection工具类为操作List集合提供了几个有用的方法: reverse().shuffle().sort().swap().rotate(). 小例子: 使用shuffle(),方法模拟洗 ...

随机推荐

  1. System.Net.Mail 详细讲解

    http://blog.csdn.net/liyanwwww/article/details/5507498

  2. Laravel5.1学习笔记8 Blade模板

    简介 模板继承 定义一个页面布局模板 扩展一个页面布局模板 展示数据 控制语法的结构 Service Injection 扩展 Blade   简介 Blade 是 Laravel 提供的一个既简单又 ...

  3. Spring学习笔记之aop动态代理(3)

    Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...

  4. 安卓使用JNI-NDK

    详细配置,参考链接:http://www.jb51.net/softjc/115204.html 一  .为什么使用NDK 1.代码的保护.由于apk的java层代码很容易被反编译,而C/C++库反汇 ...

  5. [Intermediate Algorithm] - Steamroller

    题目 对嵌套的数组进行扁平化处理.你必须考虑到不同层级的嵌套. 提示 Array.isArray() 测试用例 steamroller([[["a"]], [["b&qu ...

  6. GET 请求控制器 返回绑定后HTML

    //$.get("/Home/index/" + $("#S_BookName").val(), function (data) { //MVC控制器返回Vie ...

  7. react工具库

    采用了react框架后,需要找到一些常用的库,常见的需求比如: 1)react生成二维码 2)react的轮播banner图 随着react的社区的壮大,以上的需求都有专门的库帮我们做这个: 1)re ...

  8. matlab学习使用Button Group绘制不同的正弦曲线

    创建buttongroup控件---即按钮组 再添加三个radiobutton 对其设置 buttongroup控件改Title为绘制不同正弦曲线 第一个radiobutton的string改为sin ...

  9. PAT_A1127#ZigZagging on a Tree

    Source: PAT A1127 ZigZagging on a Tree (30 分) Description: Suppose that all the keys in a binary tre ...

  10. 安装 Ubuntu 14.04 之后要做的一些事

    转自:  http://www.cnblogs.com/marcowei/p/3841342.html 安装 ubuntu14.04 之后要做的一些事 前言: 用 ubuntu14.04 也有一段时间 ...