数论,质因数,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;
} 

原文地址:https://www.cnblogs.com/zsben991126/p/10800193.html

时间: 2024-10-27 12:24:33

数论,质因数,gcd——cf1033D 好题!的相关文章

(转载)关于gcd的8题

发现其实有关gcd的题目还是挺多的,这里根据做题顺序写出8题. [bzoj2818: Gcd] gcd(x,y)=质数, 1<=x,y<=n的对数 做这题的时候,懂得了一个非常重要的转化:求(x, y) = k, 1 <= x, y <= n的对数等于求(x, y) = 1, 1 <= x, y <= n/k的对数!所以,枚举每个质数p(线性筛素数的方法见:线性时间内筛素数和欧拉函数),然后求(x, y) = 1, 1 <= x, y <= n/p的个数.

HDU3988-Harry Potter and the Hide Story(数论-质因数分解)

Harry Potter and the Hide Story Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2193    Accepted Submission(s): 530 Problem Description iSea is tired of writing the story of Harry Potter, so,

HDU1695:GCD(容斥原理+欧拉函数+质因数分解)好题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题目解析: Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. 题目又说a==c==1,所以就是求[1,b]与[1,d]中gcd等于k的个数,因为若gcd(x,y)==z,那么gcd(x/z,y/z)==1,又因为不是z的倍数的肯定不是,所以不是z的倍数的可以直接去

数论 - 欧拉函数模板题 --- poj 2407 : Relatives

Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11372   Accepted: 5544 Description Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if ther

SPOJ PGCD - Primes in GCD Table (好题! 莫比乌斯反演+分块求和优化)

PGCD - Primes in GCD Table Johnny has created a table which encodes the results of some operation -- a function of two arguments. But instead of a boring multiplication table of the sort you learn by heart at prep-school, he has created a GCD (greate

(hdu 2.1.4)又见GCD(求最大公约数GCD的变化题)

题目: 又见GCD Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2685 Accepted Submission(s): 1327   Problem Description 有三个正整数a,b,c(0<a,b,c<10^6),其中c不等于b.若a和c的最大公约数为b,现已知a和b,求满足条件的最小的c. Input 第一行输入一个n,

ZOJ 4846 GCD Reduce (数学分析题)

题目链接 : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5440 题意: 给定一个长度为n的数列每次可以选个二元组(a[i],a[j])换成他们的最大公约数 然后问能不能再5*n次操作内把他们全部换成1, 分析: 因为每次操作都是换成GCD 因此n数的GCD肯定为1,如果不为1的话肯定不能变成1的 然后随便构造一种方法就行了,从1到n搞两遍 一定可以全变成1: 代码如下: #include <iostream> #in

CF1174C Special Coloring Problem 数论(质因数性质),构造算法

https://codeforces.com/contest/1174/problem/C 题意:给定一个数字n,构造出一个数组,在这个数组下标[2,n]的区间内,每个元素对(ai,aj)如果i和j是互质数,那么ai != aj  并且数组的最大值要尽量小 思路:2个不相同的质数之间必然是互质数,2个合数如果没有共同的质因数那么也是互质数. 那么对于数字n,构造出的数组的最大值 m>=p ,p为区间[2,n]的质数个数.我们给每个质数下标分配一个独特的值,并让其他所有合数下标等于它们各自其中任意

数论——质因数分解(C++)

一.构造质数表 (1)试除法 源代码: #include<cstdio>int n,s(1),i[1001];int main(){ scanf("%d",&n); i[1]=2; printf("2 "); for (int a=3;s<n;a++) { bool t(0); for (int b=1;b<=s;b++) if (!(a%i[b])) t=true; if (!t) { s++; i[s]=a; printf(&qu