面向对象(类与对象)

河南为何成为全国强降雨中心

  返回  

HDU6956 Pass! (BSGS数论)

2021/7/20 19:15:01 浏览:

题目链接
在这里插入图片描述
题目大意:
现在有N个人,传球,一开始球在1号手中,每秒都要传递一次球,现在告诉我们传球t秒后回到一号手中的方案数%mod的值为X,求解最小的时间t满足上述,若无解,输出-1 。

解题思路:
首先要推敲一下对于N,不同时间的时候的合法方案数的数量。
我是画了一个二叉树观察的。
显然t秒内传球方案数是(N-1)t 但是有不合法的方案数,因为最终必须回到一号。根据画的二叉树,手算发现规律如下。
t为奇数时 :
合法方案数sum=Σ(j=2;j<=t;j=j+2) (n-1)J - Σ(i=1;i<n;i=i+2) (n-1)i
t为偶数时:
合法方案数sum=Σ(j=1;j<=t;j=j+2) (n-1)J - Σ(i=2;i<n;i=i+2) (n-1)i
利用等比化简得到
sum=[(n-1)t + (-1)t (n-1) ] /n %mod=X%mod
那么不妨把分母约掉,常数移项。
等价于求解 (n-1)t = m的最小正整数t的解,BSGS算法即可
注意对于奇数的解ans必须也是奇数,同理偶数。

#include<bits/stdc++.h>
#include <map>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <unordered_map>
#define ll long long
#define int ll
using namespace std ;
unordered_map<ll, int> H ;
int N, M,  P,ans ; // N ^x = M (mod P)
//const int P=998244353;
inline ll gcd(ll a, ll b)
{
    if (!b)
        return a ;
    return gcd(b, a % b) ;
}
inline ll expow(ll a, ll b, ll mod)
{
    ll res = 1 ;
    while (b)
        res = ((b & 1)?res * a % mod : res), a = a * a % mod, b >>= 1 ;
    return res ;
}
inline ll exgcd(ll &x, ll &y, ll a, ll b)
{
    if (!b)
    {
        x = 1, y = 0 ;
        return a ;
    }
    ll t = exgcd(y, x, b, a % b) ;
    y -= x * (a / b) ;
    return t ;
}
inline ll BSGS(ll a, ll b, ll mod, ll qaq)
{
    H.clear() ;
    ll Q, p = ceil(sqrt(mod)), x, y ;
    exgcd(x, y, qaq, mod), b = (b * x % mod + mod) % mod,
                           Q = expow(a, p, mod), exgcd(x, y, Q, mod), Q = (x % mod + mod) % mod ;
    for (ll i = 1, j = 0 ; j <= p ; ++ j, i = i * a % mod)
        if (!H.count(i))
            H[i] = j ;
    for (ll i = b, j = 0 ; j <= p ; ++ j, i = i * Q % mod)
        if (H[i])
            return j * p + H[i] ;
    return -1 ;
}
inline ll exBSGS()
{
    ll qaq = 1 ;
    ll k = 0, qwq = 1 ;
    if (M == 1)
        return 0 ;
    while ((qwq = gcd(N, P)) > 1)
    {
        if (M % qwq)
            return -1 ;
        ++ k, M /= qwq, P /= qwq, qaq = qaq * (N / qwq) % P ;
        if (qaq == M)
            return k ;
    }
    return (qwq = BSGS(N, M, P, qaq)) == -1 ? -1 : qwq + k ;
}
//N^x =m%p

signed main()
{
    ll t;
    scanf("%lld",&t);

    while(t--)
    {
        ll rnmgb=9999999999999999;
        P=998244353;
        ans=0;
        ll no=0;
        ll lcj;
        ll nm;
        scanf("%lld%lld",&N,&lcj);
        nm=N;
        ll   lcj1=((lcj*N)%P+(N-1)+P)%P;  // t奇数
        ll   lcj2=((lcj*N)%P-(N-1)+P)%P; // 偶数
        M=lcj1;
        N--;
        N %= P, M %= P, ans = exBSGS() ;
        if(ans<0||ans%2!=1)
        {
            no++;
        }
        else
        {
            rnmgb=min(rnmgb,ans);

        }
        P=998244353;
        ans=0;
        N=nm-1;
        M=lcj2;
        N %= P, M %= P, ans = exBSGS() ;
        if(ans<0||ans%2!=0)
        {
            no++;
        }
        else
        {

            rnmgb=min(rnmgb,ans);
        }
        if(no==2)
        {
            printf("-1\n");
            continue;
        }
        printf("%lld\n",rnmgb);

    }

}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号