stl+数论——1247D

其实也不算很难想,每个元素质因子分解后的p^c的p和c用pair的形式存在每个元素vector里

要去前面找一个数使得所有指数相加是k的倍数,那么把vector里的所有c 模 k,然后去找前面互补的数的个数,可以用map存下前面元素模完k之后的vector,然后答案加一加就行

注意:如果a本身就是一个k次数,即其所有质因子的指数都是k的倍数,那么这种情况要单独处理一下

套了三个stl,一开始不敢写。。。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100005
ll n,k,a[N],x,cnt[N];
 
int vis[N],prime[N],m;
void init(){
    for(int i=2;i<=100000;i++){
        if(!vis[i]){
            prime[++m]=i;
        }
        for(int j=1;j<=m;j++){
            if(prime[j]*i>100000)break;
            vis[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
 
ll p[N],c[N],mm;
void divide(ll x){
    mm=0;
    for(int i=1;i<=m;i++){
        if(prime[i]>x)break;
        if(x%prime[i]!=0)continue;
        p[++mm]=prime[i];c[mm]=0;
        while(x%prime[i]==0)
            x/=prime[i],c[mm]++;
    }
    if(x>1)
        c[++m]=1,p[mm]=x;
}
 
map<vector<pair<int,int> >,int>mp;
vector<pair<int,int> >v[N];
 
int main(){
    init();
 
    cin>>n>>k;
    ll ans=0,tot=0;
 
    for(int i=1;i<=n;i++){
        cin>>a[i];
        divide(a[i]);
        for(int j=1;j<=mm;j++){
            c[j]%=k;
            if(c[j]!=0)
                v[i].push_back(make_pair(p[j],c[j]));
        }
 
        if(v[i].size()==0){
            ans+=tot;
            tot++;
            continue;
        }
 
        vector<pair<int,int> >tmp;
        for(int j=0;j<v[i].size();j++){
            pair<int,int> p;
            p.first=v[i][j].first;
            p.second=k-v[i][j].second;
            tmp.push_back(p);
        }
        ans+=mp[tmp];
 
        mp[v[i]]++;
    }
 
    cout<<ans<<'\n';
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/11746199.html