zoukankan      html  css  js  c++  java
  • [jzoj 4668] [NOIP2016提高A组模拟7.19] 腐败 解题报告(质数分类+慢速乘)

    题目链接:

    http://172.16.0.132/senior/#main/show/4668

    题目:

    题解:

    考虑把A数组里的每个元素分解质因数,对于每个质因数开一个vector存一下包含这个质因数的元素对应的这个质因数的指数

    我们可以枚举质因数分别处理。为什么时间复杂度是对的呢?因为对于任何一个元素质因数种类是不会很多的,而对于每个质因数我们仅考虑包含它的数而不是全部扫一遍,因而是对的

    枚举质因数之后,我们得到它对应的指数序列。对于小于等于根号1e7的质因数,考虑把这个指数序列从小到大,对于某个位置与之前位置的贡献就是靠前位置的指数,因此我们不断累加前缀统计答案就好了;对于另外的质因数,可以发现包含它的指数序列只能是1,所以我们不需要排序可以直接得到答案(注意到要求计算的数列其实就是元素之间两两只算一次,但注意还需要算上和本身的gcd)

    这个模数比较坑,直接乘取模的话会爆long long,因此我们采用慢速乘(不是类似快速幂的那种)

    比如x*y,我们令inf=1e7

    $a1=x mod inf$

    $a2=x/inf$

    $b1=y mod inf$

    $b2=y/inf$

    我们拆开来计算就是了,具体看代码

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    const int N=4e4+15;
    const ll mo=1e11+9;
    const int M=1e6+15;
    const ll inf=1e7+15;
    int n,cnt;
    int a[N],vis[inf];
    ll p[N];
    vector <int> pi[M];
    inline int read()
    {
        char ch=getchar();int s=0,f=1;
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    void div(int x)
    {
        for (int i=2;i*i<=x;i++)
        {
            if (x%i) continue;
            if (!vis[i]) p[++cnt]=i,vis[i]=cnt;
            int s=0;
            while (x%i==0) x/=i,++s;
            pi[vis[i]].push_back(s);
        }   
        if (x>1) 
        {
            if (!vis[x]) p[++cnt]=x,vis[x]=cnt;
            pi[vis[x]].push_back(1);
        }
    }
    ll mul(ll x,ll y)
    {
        ll a1=x%inf;
        ll a2=x/inf;
        ll b1=y%inf;
        ll b2=y/inf;
        ll re=0;
        re=(re+a2*inf%mo*b2%mo*inf%mo)%mo;
        re=(re+a2*inf%mo*b1%mo)%mo;
        re=(re+a1*inf%mo*b2%mo)%mo;
        re=(re+a1*b1%mo)%mo;
        return re;
    }
    ll qpow(ll x,ll y)
    {
        ll re=1;
        for (;y;y>>=1,x=mul(x,x)) if (y&1) re=mul(re,x);
        return re;
    }
    int main()
    {
        n=read();
        for (int i=1;i<=n;i++) a[i]=read(),div(a[i]);
        ll ans=1;
        for (int i=1;i<=cnt;i++)
        {
            if (1ll*p[i]*p[i]<=inf)
            {
                int pnt=pi[i].size();
                sort(pi[i].begin(),pi[i].end());
                ll s=0;
                for (int j=0;j<pnt;j++)
                {
                    ans=mul(ans,qpow(p[i],s));
                    s+=pi[i][j];
                }
            }
            else 
            {
                ll c=pi[i].size();
                ans=mul(ans,qpow(p[i],c*(c-1)/2));
            }
        }
        for (int i=1;i<=n;i++) ans=mul(ans,1ll*a[i]);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    java学习笔记(12) —— Struts2 通过 xml /json 实现简单的业务处理
    java学习笔记(11) —— Struts2与Spring的整合
    java学习笔记(10) —— ActionContext、ServletActionContext、ServletRequestAware用法
    PLY调试笔记
    头条暑期训练营往期题目及个人答案
    OpenStack创建网络和虚拟机、dhcp设备、虚拟路由器、虚拟机访问外网原理分析
    训练模型千万条,节省运存第一条
    编译器
    贝叶斯调参原理总结
    CNN原理+超参数优化
  • 原文地址:https://www.cnblogs.com/xxzh/p/9874670.html
Copyright © 2011-2022 走看看