BZOJ1965: [Ahoi2005]SHUFFLE 洗牌
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1965
找规律可知,设答案为x,有x*2^m%(n+1)=L
然后快速幂+逆元就可以了。
#include<cstring> #include<iostream> #include<cstdio> #include<queue> #include<cmath> #include<algorithm> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define low(x) (x&(-x)) #define maxn 505 #define inf int(1e9) #define mm 1000000007 #define ll long long using namespace std; ll n,m,p,x,y,l,a; ll read(){ ll x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } ll Pow(ll x,ll y){ ll ans=1; while (y){ if (y&1) ans=ans*x%p; x=x*x%p; y/=2; } return ans; } ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; if (b==0) { x=1; y=0; return a; } d=exgcd(b,a%b,y,x); y-=a/b*x; } int main(){ n=read(); m=read(); l=read(); p=n+1; a=Pow(2,m); exgcd(a,p,x,y); x=(x%p+p)%p; printf("%lld\n",x*l%p); return 0; }