• CF1033D Divisors 题解


    Codeforces
    Luogu

    Description.

    \(n\) 个数 \(\{a_i\}\),每个数有 \(3\sim 5\) 个因数。
    \(\prod a_i\) 的因数个数。

    \(n\le 500,a_i\le 2\times 10^{18}\)

    Solution.

    考虑 \(3\sim 5\) 个因数有那几种可能:

    1. \(x^4,x\in\text{prime}\)
    2. \(x^3,x\in\text{prime}\)
    3. \(x^2,x\in\text{prime}\)
    4. \(a\cdot b,a,b\in\text{prime}\)

    1 2 3 肯定可以直接 \(O(1)\) 判断,重点在 4。
    应该可以 Pollard-rho,然后就直接做完了。

    但是这边有一个挺好的套路,就是我们只需要考虑重复出现的因数。
    所以我们可以两两求 \(\gcd\),如果 \(\gcd \ne 1\) 那肯定有重复出现的。
    然后就做完了。

    可能会炸精,所以 1 2 3 可以直接 \(\mathcal O(\log)\) 判断。

    Coding.

    点击查看代码
    //Coded by leapfrog {{{
    //Coded on 2021.10.26
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int N=505,P=998244353;const double eps=1e-8;
    int n,at,cn[N];ll a[N];map<ll,int>mp,fg;
    inline ll chk2(ll w) {ll q=sqrt(w)+eps;return q*q==w?q:-1;}
    inline ll chk3(ll w)
    {
    	ll rs=0;for(ll L=0,R=1259922,md=(L+R)>>1;L<=R;md=(L+R)>>1)
    		if(md*md*md<=w) rs=md,L=md+1;else R=md-1;
    	if(1ll*rs*rs*rs==w) return rs;else return -1;
    }
    inline ll chk4(ll w) {ll f=chk2(w);return ~f?chk2(f):f;}
    int main()
    {
    	read(n);for(int i=1;i<=n;i++) read(a[i]);
    	ll v=0;for(int i=1;i<=n;i++)
    	{
    		if(~(v=chk4(a[i]))) mp[v]+=4;
    		else if(~(v=chk3(a[i]))) mp[v]+=3;
    		else if(~(v=chk2(a[i]))) mp[v]+=2;
    		else a[++at]=a[i],cn[at]=2,fg[a[i]]++;
    	}
    	for(int abc=2;abc--;) for(int i=1;i<=at;i++) for(int j=i+1;j<=at;j++)
    		if((v=__gcd(a[i],a[j]))!=1&&!fg[v]) mp[v];
    	for(auto &x:mp) for(int i=1;i<=at;i++) if(a[i]%x.first==0) fg[a[i]]--,mp[a[i]/x.first]++,x.second++,a[i]=1;
    	int rs=1;for(auto x:mp) rs=1ll*rs*(x.second+1)%P;
    	for(auto x:fg) rs=1ll*rs*(x.second+1)%P*(x.second+1)%P;
    	return printf("%d\n",rs),0;
    }
    
  • 相关阅读:
    使用js给数组去重的3种常用方法
    JS操作DOM元素属性和方法
    打开新窗口并运行代码
    html5 中doctype 格式
    html htm shtml 区别
    RML Utilities for SQL Server工具
    [转载]项目经理和产品经理的区别
    sublime text 3 快捷键大全以及配置编译环境
    CSS的四种引入方式
    软件系统需求分析策划方案
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15469450.html
Copyright © 2020-2023  润新知