[Codeforces 1246B] Power Products (STL+分解质因数)

[Codeforces 1246B] Power Products (STL+分解质因数)

 题面

给出一个长度为\(n\)的序列\(a_i\)和常数k,求有多少个数对\((i,j)\)满足\(a_i \times a_j = x^k (x \in \mathbb{N}^+)\)。即这两个数乘起来恰好为一个正整数的\(k\)次方

\(a_i,n \leq 10^5\)

分析

考虑\(x^k\)的质因数分解式 , 那么每一项的指数一定是k的倍数,即 \(k|x_i\).

因此对于每个 \(a_i\), 把它的质因数分解结果\(\sum p_i^{x_i}\)记录在一个数组中,每个元素形如\((p_i, x_i \ \mathrm{mod}\ k )\)

那么 \(a_j\)的质因数分解为 $\sum p_i^{k-x_i ?\mathrm{mod} k } $.

所以只要求有多少个数组满足每一项都是$ (p_i,k-x_i \mathrm{mod}?k) $.用 map< vector< pair<int,int> >, int> cnt; 存储就可以了

每个数组的大小为 \(O(\log n)\) ,总时间复杂度为 \(O(n \log ^2 n)\)

 代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#define maxv 100000
#define maxn 100000
using namespace std;
typedef long long ll;
int n,k;
map< vector< pair<int,int> >, int> cnt;
vector< pair<int,int> >p1,p2;
int a[maxn+5];
int vis[maxv+5];
int minprime[maxv+5];
int prime[maxv+5];

void sieve(int n) {
    vis[1]=1;
    for(int i=2; i<=n; i++) {
        if(!vis[i]) {
            minprime[i]=i;
            prime[++k]=i;
        }
        for(ll j=1; j<=k&&(ll)i*prime[j]<=n; j++) {
            minprime[(ll)i*prime[j]]=prime[j];
            vis[(ll)i*prime[j]]=1;
            if(!(i%prime[j])) break;
        }
    }
}

void divide(int x) {
    if(!vis[x]) {
        p1.push_back(make_pair(x,1));
        p2.push_back(make_pair(x,k-1));
        return;
    }
    while(x>1) {
        int t=minprime[x],u=0;;
        while(x%t==0&&x!=1) {
            x/=t;
            u=(u+1)%k;
        }
        if(u!=0){
            p1.push_back(make_pair(t,u));
            p2.push_back(make_pair(t,k-u));
        }
    }
}

void print(vector< pair<int,int> > &x){
    for(int i=0;i<x.size();i++){
        printf("(%d,%d) ",x[i].first,x[i].second);
    }
    printf("\n");
}
int main(){
    sieve(100000);
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        p1.clear();
        p2.clear();
        divide(a[i]);
//      print(p1);
//      print(p2);
        ans+=cnt[p2];
        cnt[p1]++;

    }
    printf("%I64d\n",ans);
}

原文地址:https://www.cnblogs.com/birchtree/p/11746161.html

时间: 2024-10-08 05:38:10

[Codeforces 1246B] Power Products (STL+分解质因数)的相关文章

[CodeForces - 1225D]Power Products 【数论】 【分解质因数】

[CodeForces - 1225D]Power Products [数论] [分解质因数] 题目描述 Time limit 2000 ms Memory limit 524288 kB Source Technocup 2020 - Elimination Round 2 Tags hashing math number theory *1900 Site https://codeforces.com/problemset/problem/1225/D 题面 Example Input 6

Codeforces 1247D. Power Products

传送门 要满足存在 $x$ ,使得 $a_i \cdot a_j = x^k$ 那么充分必要条件就算 $a_i \cdot a_j$ 质因数分解后每个质因数的次幂都要为 $k$ 的倍数 证明显然 设 $a_i=\sum_{j=1}^{x}p_j^{t_j}$ ,那么不妨变成 $\sum_{j=1}^{x}p_j^{t_j \mod k}$ 然后考虑固定 $j$,设 $a_j=\sum_{k=1}^{x}p_k^{t_k}$ ,只要求有多少 $a_i$ 的值为 $\sum_{k=1}^{x}p_k

Codeforces 893E Counting Arrays:dp + 线性筛 + 分解质因数 + 组合数结论

题目链接:http://codeforces.com/problemset/problem/893/E 题意: 共q组数据(q <= 10^5),每组数据给定x,y(x,y <= 10^6). 问你有多少种长度为y,乘积为x的整数数列.(可以有负数) 题解: 首先考虑数列只有正整数的情况. 将x分解质因数:x = ∑ a[i]*p[i] 由于x较大,所以要先用线性筛求出素数,再枚举素数分解质因数. 那么一个乘积为x的数列可以看做,将x的所有∑ p[i]个质因子,分配到了y个位置上. 设f(i)

【分解质因数】【树状数组】【快速幂】codeforces 2014 ACM-ICPC Vietnam National Second Round E. ACM

乘除都在150以内,分解质因数后发现只有35个,建立35个树状数组/线段树,做区间加.区间查询,最后快速幂起来. #include<cstdio> #include<cstring> using namespace std; #define N 50001 typedef long long ll; ll Quick_Pow(ll a,ll p,ll MOD) { if(!p) return 1; ll ans=Quick_Pow(a,p>>1,MOD); ans=an

poj 1730Perfect Pth Powers(分解质因数)

Perfect Pth Powers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16746   Accepted: 3799 Description We say that x is a perfect square if, for some integer b, x = b2. Similarly, x is a perfect cube if, for some integer b, x = b3. More g

分解质因数模板

/*==================================================*| 分解质因数,可能有些地方需要改为long long \*==================================================*/ const int MAXN=100010; int prm[MAXN+1]; bool is[MAXN+1]; int getprm(int n){ int i, j, k = 0; int s, e = (int)(sqrt

java编程题 --分解质因数

package Solve; import java.util.Scanner; public class Solve { static Scanner scan = new Scanner(System.in); public static void main(String[] args) { System.out.println("请输入一个正整数:"); int num = scan.nextInt(); System.out.print(num + " = "

POJ 2773 Happy 2006 (分解质因数+容斥+二分 或 欧几里德算法应用)

Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10309   Accepted: 3566 Description Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7, 9...are a

codevs 1792 分解质因数

1792 分解质因数 题目描述 Description 编写一个把整数N分解为质因数乘积的程序. 输入描述 Input Description 输入一个整数 N 输出描述 Output Description 输出 分解质因数 .拆成几个质数相乘的形式,质数必须从小到大相乘 样例输入 Sample Input 756 样例输出 Sample Output 756=2*2*3*3*3*7 #include<cstdio> #include<cmath> #include<str