zoukankan      html  css  js  c++  java
  • BZOJ 1965 洗牌(扩展欧几里得)

    容易发现,对于牌堆里第x张牌,在一次洗牌后会变成2*x%(n+1)的位置。

    于是问题就变成了求x*2^m%(n+1)=L,x在[1,n]范围内的解。

    显然可以用扩展欧几里得求出。

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <bitset>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi acos(-1.0)
    # define eps 1e-8
    # define MOD 1000000007
    # define INF 1000000000
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    int Scan() {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int N=5005;
    //Code begin...
    
    LL mult_mod(LL a, LL b, LL c){
        a%=c; b%=c;
        LL ret=0, tmp=a;
        while (b){
            if (b&1) {
                ret+=tmp;
                if (ret>c) ret-=c;
            }
            tmp<<=1;
            if (tmp>c) tmp-=c;
            b>>=1;
        }
        return ret;
    }
    LL pow_mod(LL a, LL n, LL mod){
        LL ret=1, temp=a%mod;
        while (n) {
            if (n&1) ret=mult_mod(ret,temp,mod);
            temp=mult_mod(temp,temp,mod);
            n>>=1;
        }
        return ret;
    }
    LL extend_gcd(LL a, LL b, LL &x, LL &y){
        if (a==0&&b==0) return -1;
        if (b==0) {x=1; y=0; return a;}
        LL d=extend_gcd(b,a%b,y,x);
        y-=a/b*x;
        return d;
    }
    int main ()
    {
        LL n, m, l, a, b, d, x, y, mod;
        scanf("%lld%lld%lld",&n,&m,&l);
        a=pow_mod(2,m,n+1); b=n+1;
        d=extend_gcd(a,b,x,y); x=x*l/d; mod=b/d;
        x=(x%mod+mod)%mod;
        printf("%lld
    ",x);
        return 0;
    }
    View Code
  • 相关阅读:
    CentOS Linux下VNC Server远程桌面配置详解
    Java 中的悲观锁和乐观锁的实现
    spring @configuration使用
    MySQL 汉字拼音
    chmod用数字来表示权限的方法
    C语言创建删不掉的目录
    Android小经验
    系统清理——查找大文件
    最全Pycharm教程(42)——Pycharm扩展功能之Emacs外部编辑器
    怎样学习程序
  • 原文地址:https://www.cnblogs.com/lishiyao/p/6864040.html
Copyright © 2011-2022 走看看