bzoj 1965 数学

  首先我们可以发现每张牌的对应关系,假设序号为x的牌,经过一次洗牌后的位置为:

    2*x     x<=n/2

    2*(x-n/2)-1 x>n/2

  那么我们可以将下面的式子化简,变成2*x-n-1,其实这个就是2*x%(n+1),那么经过m次变换,x的位置为2^m*x%(n+1),设最后的答案为x,那么我们可以列出式子

    2^m*x%(n+1)=l,拓展欧几里得做就行了。

/**************************************************************
    Problem: 1965
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:804 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#define LL long long
 
using namespace std;
 
LL n,m,l;
LL x,y;
 
LL mi(LL x) {
    LL ans=1,sum=2;
    while (x) {
        if (x&1) ans=(ans*sum)%(n+1);
        sum=(sum*sum)%(n+1);
        x>>=1;
    }
    return ans;
}
 
void ex_gcd(LL a,LL b) {
    if (!b) {
        x=l; y=0; return;
    }
    ex_gcd(b,a%b);
    LL z=x;
    x=y;
    y=z-(a/b)*y;
}
 
int main() {    
    scanf("%lld %lld %lld",&n,&m,&l);
    LL a=mi(m),b=n+1;
    ex_gcd(a,b);
    x=((x%b)+b)%b;
    printf("%lld\n",x);
    return 0;
}

 

posted on 2014-04-01 13:30  BLADEVIL  阅读(193)  评论(0编辑  收藏  举报