zoukankan      html  css  js  c++  java
  • 4668. 【NOIP2016提高A组模拟7.19】腐败

    Description

    识时务者,俊杰上课没事干,腐起败来。他磨着你给他解决一道题:
    给你一个长度为n 序列 A,求 \(\prod_{i=1}^{n} \prod_{j=i}^{n} \gcd(A[i], A[j])\)
    即从序列中选两个数 i,j 出来, 满足 i\(\le\)j,求他们 gcd,记为 k 。然后把所有情况的 i 和 j 对应的 k 给乘起来。
    答案太大了,请你对 100000000009 取模。
    小心点,这个模数很奇怪。

    Solution

    对于每个数来计算贡献是不行的,考虑对于每个质因数计算贡献。

    \(\mathrm{vector}\) 来记录每个质因数的指数序列。

    统计出每个质因数的指数序列后,排序,那么对于一个质因数的指数序列,前面的数和后面的数的 \(\gcd\) 在当前这个质因数上的贡献是 \(p^{\sum x}\)\(p\) 表示当前这个质因数,\(\sum x\) 是指此前的指数前缀和)。

    另外,对于指数序列全是 1 的质因数,可以直接 \(\mathcal O(1)\) 计算。

    Code

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #define N 40005
    #define M 1000005
    #define mod 100000000009
    #define inf 12345678  
    #define ll long long
    using namespace std;
    vector<ll> pr[M];
    int n,num,bj[inf];
    ll ans,a[N],p[N];
    ll ksc(ll x,ll y)
    {
        ll x1=x/inf,x2=x%inf,y1=y/inf,y2=y%inf;
        ll res=0;
        res=(res+x1*y1%mod*inf%mod*inf%mod)%mod;
        res=(res+x1*inf%mod*y2%mod)%mod;
        res=(res+x2*y1%mod*inf%mod)%mod;
        res=(res+x2*y2%mod)%mod;
        return res;
    }
    ll ksm(ll x,ll y)
    {
        ll res=1;
        while (y)
        {
            if (y&1) res=ksc(res,x)%mod;
            x=ksc(x,x)%mod;
            y>>=1;
        }
        return res;
    }
    void fenjie(ll x)
    {
        for (int i=2;i*i<=x;++i)
        {
            if (x%i!=0) continue;
            if (!bj[i]) p[++num]=i,bj[i]=num;
            int s=0;
            while (x%i==0) x/=i,++s;
            pr[bj[i]].push_back(s);
        }
        if (x>1)
        {
            if (!bj[x]) p[++num]=x,bj[x]=num;
            pr[bj[x]].push_back(1);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;++i)
            scanf("%lld",&a[i]),fenjie(a[i]);
        ans=1;
        for (int i=1;i<=num;++i)
        {
            if (p[i]*p[i]<=inf)
            {
                int len=pr[i].size();
                sort(pr[i].begin(),pr[i].end());
                ll sum=0;
                for (int j=0;j<len;++j)
                {
                    ans=ksc(ans,ksm(p[i],sum));
                    sum+=pr[i][j];
                }
            }
            else
            {
                ll len=pr[i].size();
                ans=ksc(ans,ksm(p[i],len*(len-1)/2));
            }
        }
        for (int i=1;i<=n;++i)
            ans=ksc(ans,a[i]);
        printf("%lld\n",ans);
        return 0;
    }
    
  • 相关阅读:
    JQuery之动画效果
    JS (随着鼠标的移动,旁边显示放大图)
    jQuery 事件和动画
    jQuery 概述
    CSS (层叠样式表)
    css的文章部分的基本语句
    HTML基本语法
    Web
    JavaScript预解析案例,JavaScript预解析题目
    JavaScript预解析 变量提升与函数提升
  • 原文地址:https://www.cnblogs.com/Livingston/p/15758483.html
Copyright © 2011-2022 走看看