cf 1225D - Power Products

cf 1225D - Power Products

https://codeforces.com/problemset/problem/1225/D
题意:给一些数,问满足下列条件的数对的数量,对于给定的 k, ∃ x , s . t .   a i ∗ a j = x k \exists x, s.t. \ a_i * a_j = x^k ∃x,s.t. ai​∗aj​=xk。
思路:容易想到分解质因数,再将指数都对于k取模,将所有的数都这样处理,称为化简。同时对于这些数剩下的质因数,我们可以根据 k 算得与之对应满足条件的 b[i], b[i] 的的质因数的指数和 a[i] 对应的质因数的指数相加为k,然后在其他数中找是否存在化简后的这样的数,及其个数。注意这里在计算的时候要考虑到所有a的大小不超过1e5, 所以在计算对应的b的时候,如果超过1e5就说明没有。(不然re一发)
over。

#include<bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int N = 1e5+10;

int p[N], cntp;
bool vis[N];

pii d[30];

int cnt[N];

int a[N];
int b[N];

int n, k;

void sieve(int n) {
    for(int i = 2; i < n; i++) {
        if(!vis[i]) p[cntp++] = i;
        for(int j = 0; j < cntp && p[j] <= n / i; j++ ){
            vis[p[j] * i] = 1;
            if(i % p[j] == 0) break;
        }
    }
}

void normalize(int idx) {
    int u = a[idx];
    int cntd = 0;
    for(int i = 0; i < cntp && u > 1; i++) {
        if(u % p[i] == 0){
            int cntt = 0;
            while(u % p[i] == 0) {
                u /= p[i];
                cntt++;
            }
            d[cntd++] = {p[i], cntt % k};
        }
    }
    if(u >= 1) d[cntd++] = {u, 1};
    u = 1;
    ll v = 1;
    for(int i = 0; i < cntd && v < N; i++) {
        if(d[i].second) {
            for(int j = 0; j < k - d[i].second && v < N; j++) 
                v *= d[i].first;
            
            for(int j = 0; j < d[i].second; j++) 
                u *= d[i].first;
        }
    }
    cnt[u]++;
    if(v < N) b[idx] = v;
    a[idx] = u;
}

int main() {
    sieve(1e3+10);
    scanf("%d%d", &n, &k);

    for(int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        normalize(i);
    }

    ll ans = 0;
    for(int i = 0; i < n; i++) {
        ans += cnt[b[i]];
        if(a[i] == b[i])  ans --;
    }
    ans >>= 1;
    printf("%lld\n", ans);
    return 0;
}

feel good, 自己想出来的题,但是想出来之后又觉得思路很简单, 不应该想这么久

上一篇:板刷cf dp


下一篇:树上差分