题目描述
题解
每一次洗牌:
对于
i<=n2
,
i−>2∗i
对于
i>n2
,
i−>(i−n2−1)∗2+1=2∗i−(n+1)
所以对于所有的
i
,
洗
m
次牌之后,
那么洗
m
次牌之后位置是
扩欧求逆元,并且用快速乘防止炸long long
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
LL n,m,l,ans;
LL fast_mul(LL a,LL p)
{
LL ans=0LL;
for (;p;p>>=1LL,a=(a+a)%(n+1))
if (p&1)
ans=(ans+a)%(n+1);
return ans;
}
LL fast_pow(LL a,LL p)
{
LL ans=1LL;
for (;p;p>>=1LL,a=fast_mul(a,a)%(n+1))
if (p&1LL)
ans=fast_mul(ans,a)%(n+1);
return ans;
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
if (!b) x=1LL,y=0LL;
else exgcd(b,a%b,y,x),y-=a/b*x;
}
LL inv(LL a,LL b)
{
LL x=0LL,y=0LL;
exgcd(a,b,x,y);
x=(x%b+b)%b;
if (!x) x+=b;
return x;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&l);
ans=fast_mul(l%(n+1),inv(fast_pow(2LL,m),n+1))%(n+1);
printf("%lld\n",ans);
}