zoukankan      html  css  js  c++  java
  • Groundhog Chasing Death【质因子】-2020牛客暑期多校9

    题意

    已知 (a,b,c,d,x,y),求:

    [prod_{i=a}^{b}{prod_{j=c}^{d}{gcd(x^i,y^j)}} mod 998244353 ]

    (0⩽a,b,c,d⩽3×10^6,0<x,y⩽10^9,a⩽b,c⩽d)

    题目链接:https://ac.nowcoder.com/acm/contest/5674/E

    分析

    从质因子的角度入手,最终的结果一定是 (gcd(x,y)) 的各质因子的若干幂相乘的形式,因此可以先把个质因子的幂求出,最后再用快速幂求解。

    假设对于当前的第 (i) 个质因子,在 (x) 中的幂为 (gx),在 (y) 中的幂为 (gy),那么最终结果中第 (i) 个质因子的幂为:

    [sum_{i=a}^{b}{sum_{j=c}^{d}{min(i·gx,j·gy)}} ]

    对此,可以枚举第一层,然后利用分界点 (O(1)) 求出第二层的结果。

    另外,由于质因子的幂比较大,会爆 (long long),可以用 (\_\_int128) 或者欧拉降幂。另外,如果刚好可以整除,对于除数,可以不用取逆元。比赛的时候求 (2)(mod-1) 下的逆元,结果发现没有,最后不得不用 (\_\_int128) 过的。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=998244353;
    const int N=3e6+6;
    int f[12],cnt,e[2][12];
    int gcd(int n,int m)
    {
        return m?gcd(m,n%m):n;
    }
    void divide(int n)
    {
        cnt=0;
        for(int i=2;i*i<=n;i++)
        {
            if(n%i==0)
            {
                f[++cnt]=i;
                while(n%i==0) n/=i;
            }
        }
        if(n>1) f[++cnt]=n;
    }
    void cunt(int x,int p)
    {
        for(int i=1;i<=cnt;i++)
        {
            e[p][i]=0;
            while(x%f[i]==0)
            {
                e[p][i]++;
                x/=f[i];
            }
        }
    }
    ll power(ll a,ll b)
    {
        ll res=1;
        a%=mod;
        while(b)
        {
            if(b&1) res=res*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return res;
    }
    ll solve(int a,int b,int c,int d,int p)
    {
        ll ans=1,res=0;
        for(int i=a;i<=b;i++)
        {
            ll t=1LL*i*e[0][p];//cout<<"t="<<t<<endl;
            ll w=t/e[1][p];//分界点
            if(w<c)
            {
                res=(res+1LL*(d-c+1)*t)%(mod-1);
                continue;
            }
            if(w>=d)
            {
                res=(res+1LL*(c+d)*(d-c+1)/2*e[1][p])%(mod-1);
                continue;
            }
            ll u=1LL*(c+w)*(w-c+1)/2*e[1][p];
            res=(res+t*(d-w)+u)%(mod-1);
        }
        ans=ans*power(1LL*f[p],res%(mod-1))%mod;
        return ans;
    }
    int main()
    {
        int a,b,c,d,x,y;
        scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&x,&y);
        int g=gcd(x,y);
        ll res=1;
        divide(g);
        cunt(x,0);
        cunt(y,1);
        for(int i=1;i<=cnt;i++)
        {
            ll tmp=solve(a,b,c,d,i);
            res=(res*tmp%mod+mod)%mod;
        }
        printf("%lld
    ",res);
        return 0;
    }
    
    
  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13460223.html
Copyright © 2011-2022 走看看