• 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;
    }
    
    
  • 相关阅读:
    大的FIbonacci数列_Java求法
    HDU1134_Game of Connections 卡特兰数
    oracle中查询锁表
    SpringBoot之使用Druid连接池以及SQL监控和spring监控
    用vue封装插件并发布到npm
    vue 预览 Excel 表格
    vue + elementUI 表格 底部 合计总数
    springboot项目中实现访问druid内置监控页面
    解决Elementui eltable合计 showsummary不显示,样式混乱问题
    Druid连接池:慢查询监控
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13460223.html
Copyright © 2020-2023  润新知