zoukankan      html  css  js  c++  java
  • 数论,质因数,gcd——cf1033D 好题!

    直接筛质数肯定是不行的

    用map<ll,ll>来保存质因子的指数

    考虑只有3-5个因子的数的组成情况

    必定是a=pq or a=p*p or a=p*p*p or a=p*p*p*p

    先用二分判后面三种情况

    然后判第一种情况

    由于不知道pq,而且无法直接求,我们间接用 d=gcd(a[i],a[j]) 来求

    如果1<d<a[i],那么a[i]两个因数就可以确定是d,a[i]/d

    反之a[i]两个因数未出现过,pq直接计算到贡献里去

    但是可能有和a[i]相等的数,所以我们不先计算这样pq的数量,而是另外开一个map<ll,ll>来计算像a[i]这样的不能直接求出因子的数及其个数

    然后求答案时再和另一个map分开统计,相乘

    #include<bits/stdc++.h>
    #include<map>
    using namespace std;
    #define ll long long
    #define mod 998244353
    map<ll,ll>mp;
    map<ll,ll>::iterator it;
    int n,tot;
    ll a[505];
    ll calc4(ll x){
        ll l=1,r=37607,mid;
        while(l<=r){
            mid=l+r>>1;
            ll t=mid*mid*mid*mid;
            if(t==x)return mid;
            else if(t>x)r=mid-1;
            else l=mid+1;
        }
        return -1;
    }
    ll calc3(ll x){
        ll l=1,r=1259922,mid;
        while(l<=r){
            mid=l+r>>1;
            ll t=mid*mid*mid;
            if(t==x)return mid;
            else if(t>x)r=mid-1;
            else l=mid+1;
        }
        return -1;
    }
    ll calc2(ll x){
        ll l=1,r=1414213563,mid;
        while(l<=r){
            mid=l+r>>1;
            ll t=mid*mid;
            if(t==x)return mid;
            else if(t>x)r=mid-1;
            else l=mid+1;
        }
        return -1;
    }
    map<ll,ll>has;
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++){
            ll p=calc4(a[i]);
            if(p!=-1){mp[p]+=4;continue;}
            p=calc3(a[i]);
            if(p!=-1){mp[p]+=3;continue;}
            p=calc2(a[i]);
            if(p!=-1){mp[p]+=2;continue;}
            
            int flag=0;
            for(int j=1;j<=n;j++){//找p
                if(i==j)continue;
                ll d=__gcd(a[i],a[j]);
                if(d!=1 && d!=a[j]){
                    mp[d]++;mp[a[i]/d]++;
                    flag=1;break;
                }
            }
            if(flag==0)has[a[i]]++;//找不到p,就把a[i]存下来 
        }
        ll ans=1;
        for(it=has.begin();it!=has.end();it++){//计算第二个map的贡献 
            ans=ans*(it->second+1)%mod*(it->second+1)%mod;
        }
        for(it=mp.begin();it!=mp.end();it++){//计算第一个map的贡献 
            ans=ans*(it->second+1)%mod;
        }
        cout<<ans<<endl;
    } 
  • 相关阅读:
    AjaxPro.2.dll基本使用
    能够按页号提取word文档文本内容的小程序,由C#实现
    Reflect反编译C#程序
    模态对话框
    【转】Google Chrome如何保存密码口令
    Android 应用的签名的基本原则
    几款keylogger
    对一个利用短链接进行钓鱼行为的小小分析
    2011年10月百度笔试 RD3—第4题
    TCP中有哪些机制保证了可靠传输
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10800193.html
Copyright © 2011-2022 走看看