【BZOJ 3884】上帝與集合的正確用法(新知識)

【題目描述】

根據一些書上的記載,上帝的一次失敗的創世經歷是這樣的:
第一天, 上帝創造了一個世界的基本元素,稱做“元”。
第二天, 上帝創造了一個新的元素,稱作“α”。“α”被定義爲“元”構成的集合。容易發現,一共有兩種不同的“α”。
第三天, 上帝又創造了一個新的元素,稱作“β”。“β”被定義爲“α”構成的集合。容易發現,一共有四種不同的“β”。
第四天, 上帝創造了新的元素“γ”,“γ”被定義爲“β”的集合。顯然,一共會有16種不同的“γ”。
如果按照這樣下去,上帝創造的第四種元素將會有65536種,第五種元素將會有2^65536種。這將會是一個天文數字。
然而,上帝並沒有預料到元素種類數的增長是如此的迅速。他想要讓世界的元素豐富起來,因此,日復一日,年復一年,他重複地創造着新的元素……
然而不久,當上帝創造出最後一種元素“θ”時,他發現這世界的元素實在是太多了,以致於世界的容量不足,無法承受。因此在這一天,上帝毀滅了世界。
至今,上帝仍記得那次失敗的創世經歷,現在他想問問你,他最後一次創造的元素“θ”一共有多少種?
上帝覺得這個數字可能過於巨大而無法表示出來,因此你只需要回答這個數對p取模後的值即可。
你可以認爲上帝從“α”到“θ”一共創造了10910^9次元素,或101810^{18}次,或者乾脆次。
一句話題意
在這裏插入圖片描述

【分析】

對於此題有一個重要的結論:
b>φ(c)b>\varphi(c)時,有
abab mod φ(c)+c(mod c)a^b\equiv a^{b\space mod \space \varphi(c)+c}\qquad \small{(mod\space c)}
由於本題指數可被認爲無窮大,所以可以直接使用上面結論。
於是令f(i)=222f(i)=2^{2^{2^{\cdots}}},則:
f(i) mod p=222mod p=2(222 mod φ(p)+p) mod p=2f(φ(p))+pf(1)=0f(i)\space \small{mod} \space p = 2^{2^{2^{\cdots}}} \small{mod} \space p = 2^{(2^{2^{2^{\cdots}}}\space mod \space \varphi(p)+p)}\space \small{mod} \space p=2^{f(\varphi(p))+p} \newline \newline f(1)=0

【代碼】

#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<int, ll> res;
inline ll ksm(ll a, ll b, ll p)
{
    ll ret = 1;
    while(b)
    {
        if(b & 1) (ret *= a) %= p;
        (a *= a) %= p, b >>= 1;
    }
    return ret;
}
inline ll phi(int x)
{
    ll ret = x;
    for(ll i = 2; i * i <= x; i++)
    {
        if(x % i == 0)
        {
            while(x % i == 0) x /= i;
            ret /= i, ret *= i - 1;
        }
    }
    if(x > 1) ret /= x, ret *= x - 1;
    return ret;
}
ll calc(int c)
{
    if(res.count(c)) return res[c];
    int ph = phi(c);
    return res[c] = ksm(2, calc(ph) + ph, c);
}
int main()
{
    int T, n;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        printf("%lld\n", calc(n));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章