zoukankan      html  css  js  c++  java
  • 【美团杯2020】平行四边形

    题:http://uoj.ac/problem/525

    分析:1 . 答案是(i,g^i%(n+1))后一项为原根的次方。采用反证法,假设有4个点:(a,g^a),(b,g^b),(c,g^c),(d,g^d);

       2 . 若形成平行四边形则要满足:(1) a-b==c-d. (2)g^a-g^b==g^c-g^d   (    化简为 g^b ( g^(a-b) - 1 ) == g^d ( g^(c-d) -1)   )

       3 . 联立(1)(2)得必须a==c&&b==d才能形成平行四边形,而我们第一项的 i 避免了这一点,所以直接求n+1的原根

    #include<bits/stdc++.h>
    #define lowbit(i) i&(-i)
    #define pb push_back
    using  namespace std;
    typedef long long ll;
    ll ksm(ll a,ll b,ll mod){
        ll t=1;
        while(b){
            if(b&1)
                t=t*a%mod;
            b>>=1;
            a=a*a%mod;
        }
        return t;
    }
    ///求原根
    ll solve(ll p,ll m){///p==phi(m)
        ll x=p;
        vector<ll>tmp;
        tmp.clear();
        for(ll i=2;i*i<=x;i++){
            if(x%i==0){
                tmp.pb(i);
                while(x%i==0)
                    x/=i;
            }
        }
        if(x>1)
            tmp.pb(x);
        for(ll i=2;;i++){
            ll flag=1;
            for(auto x:tmp){
                if(ksm(i,p/x,m)==1){
                    flag=0;
                    break;
                }
            }
            if(flag)
                return i;
        }
        return -1;
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            ll n;
            scanf("%lld",&n);
            ll g=solve(n,n+1);
            if(g==-1){
                printf("-1
    ");
            }
            else{
                for(ll i=1;i<=n;i++)
                    printf("%lld %lld
    ",i,ksm(g,i,n+1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C语言寒假大作战01
    第十二次作业
    第十一次作业
    第十周作业
    第九次作业
    第8周作业
    第七次作业
    C语言I作业12—学期总结
    第一周作业
    C语言l博客作业02
  • 原文地址:https://www.cnblogs.com/starve/p/12977294.html
Copyright © 2011-2022 走看看