zoukankan      html  css  js  c++  java
  • 欧拉定理

    第二天数论,简直听天书

    记住就行

    P4139:上帝与集合的正确用法:https://www.luogu.org/problemnew/show/P4139

    考虑扩展欧拉定理,每次对上面的式子使用扩欧

    由于对一个数不断取phi,当p为1返回0即可,所以复杂度为log(p)

    考虑到原题中的式子一定比p大,所以只用考虑定理中的第二种情况即可

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include <ext/pb_ds/priority_queue.hpp>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long ll;
    #define pii pair<int,int>
    #define mp make_pair
    #define pair_heap __gnu_pbds ::priority_queue<pii> 
    #define llinf 9000000000000000000LL
    #define B cout << "breakpoint" << endl;
    inline ll read()
    {
        ll ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1; 
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e7 + 5;
    ll pri[maxn],cnt,phi[maxn];
    bool vis[maxn];
    void init()
    {
        for(int i = 2;i <= maxn - 5;i++)
        {
            if(!vis[i]) pri[++cnt] = i,phi[i] = i - 1;
            for(int j = 1;j <= cnt && i * pri[j] <= maxn - 5;j++)
            {
                vis[i * pri[j]] = 1;
                if(i % pri[j] == 0) {phi[i * pri[j]] = phi[i] * pri[j]; break; }
                else phi[i * pri[j]] = phi[i] * phi[pri[j]]; 
            }
        }
    }
    ll power(ll a,ll b,ll p)
    {
        ll ans = 1,res = a;
        while(b)
        {
            if(b & 1) (ans *= res) %= p;
            (res *= res) %= p;
            b >>= 1;
        }
        return ans;
    }
    ll solve(ll p)
    {
        if(p == 1) return 0;
        return power(2,solve(phi[p]) + phi[p],p);
    }
    int main()
    {
        ll t = read();
        init();
        while(t--)
        {
            ll p = read();
            printf("%lld
    ",solve(p));
        }
    }
        
        
    View Code

    CF906D:power tower:https://www.luogu.org/problemnew/show/CF906D

    继续用欧拉定理,和上面一样,至多递归log层结束

    不一样的是,这道题需要考虑b与phi(p)的大小关系

    有两种解决方法:1.记录b是否真正被phi(p)模过,返回pair即可

    2.

    ll mod(ll a,ll b)
    {    return a < b ? a : a % b + b; }
    View Code

    这样取模,结果虽然还是比b大(符合原来的情况),但是再取一遍模在计算时仍然可以得到正确答案

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long ll;
    #define B cout << "breakpoint" << endl;
    inline ll read()
    {
        ll ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1; 
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e6 + 5;
    map<ll,ll> phi;
    ll n,p;
    ll a[maxn];
    ll get(ll x)
    {
        ll res = x,tp = x;
        if(phi[x]) return phi[x];
        for(int i = 2;i <= sqrt(x);i++)
        {
            if(x % i == 0)
            {
                res = res / i * (i - 1);
                while(x % i == 0) x /= i;
            }
        }
        if(x > 1) res = res / x * (x - 1);
        return phi[tp] = res;
    }
    ll mod(ll a,ll b)
    {    return a < b ? a : a % b + b; }
    ll power(ll a,ll b,ll p)
    {
        ll ans = 1,res = a;
        while(b)
        {
            if(b & 1) ans = mod(ans * res, p);
            res = mod(res * res,p);
            b >>= 1;
        }
        return ans;
    }
    ll solve(int l,int r,ll p)
    {
        if(l == r || p == 1) return mod(a[l],p);
        else return power(a[l],solve(l + 1,r,get(p)),p);
    }
    int main()
    {
        n = read();
        p = read();
        for(int i = 1;i <= n;i++) a[i] = read();
        ll q = read();
        while(q--)
        {
            ll l = read(),r = read();
            printf("%lld
    ",solve(l,r,p) % p);
        }
    }
    View Code
  • 相关阅读:
    奖学金 题解
    大数加法
    删除倒数第 N 个节点
    css中行内元素默认间隙解决方案
    vuecli3项目中优化lodash/moment使用
    谷歌浏览器input输入框自动填充数据
    vuecli3首页白屏优化
    highcharts开发交易所的行情走势图
    react-native使用flatlist上拉加载下拉刷新
    放大预览图片不失真
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/11220879.html
Copyright © 2011-2022 走看看