美团杯2020平行四边形

Posted starve

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了美团杯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

 

以上是关于美团杯2020平行四边形的主要内容,如果未能解决你的问题,请参考以下文章

美团杯2020半前缀计数(SAM)

美团杯2020半前缀计数(SAM)

UOJ#523. 美团杯2020半前缀计数 后缀自动机

uoj#529. 美团杯2020114514

"美团杯"热身题(数独)

片段着色器中未使用纹理数据 - OpenGL