bzoj1965: [Ahoi2005]SHUFFLE 洗牌

来源:互联网 发布:caj转word转换器 mac 编辑:程序博客网 时间:2024/05/31 05:28

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1965

题意:中文题。。。

分析:一个置换的题。。我们对样例进行简单的分析可知经过一次变换有(1->2,2->4,3->6,4->1,5->3,6->5),然后我们就能发现p[a]=a*2%(n+1)。。然后我们设答案为X即X=p[l],所以有X*(2^m)=l%(n+1)并且2模n+1的逆元为n/2+1,所以我们将等式变换一下就有X=l*(n/2+1)^m%(n+1),然后就只要用快速幂处理这个式子就行了,同时要注意数据是10^10可能乘爆,用快速乘即可。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=100010;const int MAX=151;const int MOD1=100000007;const int MOD2=100000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=5000011;const ll INF=10000000010;typedef unsigned long long ull;ll mul(ll a,ll b,ll M) {    ll ret=0;    for (ll i=b;i;i>>=1,a=(a+a)%M)    if (i&1) ret=(ret+a)%M;    return ret;}ll qpow(ll a,ll b,ll M) {    ll ret=1;    for (ll i=b;i;i>>=1,a=mul(a,a,M))    if (i&1) ret=mul(ret,a,M);    return ret;}int main(){    ll n,m,l,ans;    scanf("%lld%lld%lld", &n, &m, &l);    ans=l*qpow(n/2+1,m,n+1);    printf("%lld\n", (ans+n+1)%(n+1));    return 0;}/*6 2 3*/


0 0
原创粉丝点击