https://www.lydsy.com/JudgeOnline/problem.php?id=1965
假设当前位置是x,洗完一次之后变到哪里去了呢?
如果x≤n/2,那么是2x,如果x>n/2,那么是2x−n−1
因为前半部分显然存在2x≤n,而后半部分显然2x>n+1,所以我们可以认为每次操作之后都由l位置变成了2x%(n+1)位置。
那么进行了m次之后出现在了l位置,即:x∗2^m≡L(mod n+1),而n是偶数,所以必然和前面的2^m互质,所以只需要求解一个逆元就好了。
#include<bits/stdc++.h>
#define ll long long
long long pow(long long a,long long x,long long mod)
{
long long ans=1;
long long base=a;
while(x!=0)
{
if(x&1!=0)
ans=(base*ans)%mod;
base=(base*base)%mod;
x/=2;
}
return ans;
}
void exgcdd(ll a,ll b,ll& x,ll& y)
{
if(!b) {x=1;y=0;}
else{exgcdd(b,a%b,d,y,x);y-=x*(a/b);}
}
ll n , m , l;
ll multi(ll a,ll b){ll s=0;while(b){if(b&1)s=(s+a)%(n+1);a=(a+a)%(n+1);b>>=1;}return s;}
int main()
{
scanf("%lld%lld%lld",&n,&m,&l);
ll mm=pow(2,m,n+1);
ll x,y,p;
exgcdd(mm,n+1,p,x,y);
x=(x%(n+1)+n+1)%(n+1);//保证为最小正整数解
printf("%lld\n",multi(x,l));//快速乘
}