P3518 [POI2011] SEJ-Strongbox 做题记录

P3518 [POI2011] SEJ-Strongbox

Description

有一个密码箱,\(0\)\(n-1\) 中的某些整数是它的密码。且满足:若 \(a\)\(b\) 是它的密码,则 \((a+b)\bmod n\) 也是它的密码(\(a\)\(b\) 可以相等)。某人试了 \(k\) 次密码,前 \(k-1\) 次都失败了,最后一次成功了。

问,该密码箱最多有多少种不同的密码。

\(1\leq k \leq 250000,k\leq n\leq 10^{14}\)

Link

Solution

\(x\) 为密码,那么 \(2x \bmod n, 3x \bmod n,...\) 都会是密码。

我们有引理:

Lemma 1

\(x\) 为密码,那么 \(\gcd(x,n)\) 也必定是密码。

列出同余方程 \(kx \equiv\gcd(x,n) \pmod{n}\),化为 \(kx+pn=\gcd(x,n)\),方程必定有解。

Lemma 2

\(x,y\) 为密码,那么 \(\gcd(x,y)\) 也必定是密码。

首先关于 \(p,q\) 的方程 \(px+qy=\gcd(x,y)\) 一定有整数解。

在模 \(n\) 意义下,将 \(p,q\) 通过加若干次 \(n\) 变为非负整数,同余号依然成立。

\(p,q\) 一定可以全部取到非负整数。

Lemma 3

设最小的密码为 \(x\),其余密码一定是 \(x\) 的若干正整数倍。

反证法。假设最小的密码是 \(x\),存在一个密码 \(y\) 不是 \(x\) 的倍数。

那么 \(\gcd(x,y)<x\),与 \(x\) 最小矛盾。

有了上面 3 个引理,题意转化为:求最小的 \(x\),满足 \(x\mid \gcd(n,m_k)\),且 \(\forall i \in [1,k-1], x\nmid m_i\)。答案即为 \(\dfrac{n}{x}\)

\(d=\gcd(n,m_k)\)。暴力求解的时间复杂度为 \(d\) 的因子个数乘上 \(m\),无法通过。

那么我们考虑枚举 \(m_i\) 的因子。首先对于每一个 \(m_i\),对其因子集合与 \(d\) 的因子集合取交集,也就是 \(m_i \leftarrow \gcd(m_i,d)\)。此时有 \(m_i \mid d\)

接下来可以发现 \(d\) 的不同质因子数量不会超过 \(20\) 个,于是可以由此入手。

对于一个 \(m_i\),我们不断用 \(d\) 的质因子除 \(m_i\),直到 \(m_i\) 变为 \(1\),并标记途中的所有数字。

利用记忆化,我们就能保证每一个数字只被标记一次。时间复杂度变为 \(\mathcal{O(d(d)\times\omega(d))}\),可以接受。

ll n,a[N],k;
map<ll,bool> vis;
vector<ll> prd;

ll gcd(ll x,ll y){return __gcd(x,y);}

void dfs(ll x){
    if(vis.count(x)) return;
    vis[x]=1;
    for(ll i:prd){
        if(x%i==0)
            dfs(x/i);
    }
}

signed main(){
    read(n),read(k);
    for(int i=1;i<=k;i++) read(a[i]);
    ll G=gcd(a[k],n),g=G;
    for(ll i=2;i*i<=G;i++){
        if(g%i==0){
            prd.push_back(i);
            while(g%i==0) g/=i;
        }
    }
    if(g>1) prd.push_back(g);
    for(int i=1;i<k;i++) dfs(gcd(G,a[i]));
    vector<ll> d;
    for(ll i=1;i*i<=G;i++){
        if(G%i==0){
            d.push_back(i);
            if(i*i!=G) d.push_back(G/i);
        }
    }
    sort(d.begin(),d.end());
    for(ll i:d){
        if(!vis.count(i)){
            printf("%lld\n",n/i);
            return 0;
        }
    }
    puts("0");
    return 0;
}

posted @ 2025-01-18 22:12  XP3301_Pipi  阅读(30)  评论(0)    收藏  举报
Title