zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    010-1 Socket地址族AddressFamily
    011 Socket定义客户端
    003 win7如何配置adb环境变量
    002 调试工具的具体功能
    001 Nibiru SDK 调试工具介绍
    001 UI介绍
    010 socket定义服务器
    001 Lua相关链接
    000 Lua目录
    深拷贝的、浅拷贝讲解以及示例
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15469450.html
Copyright © 2011-2022 走看看