zoukankan      html  css  js  c++  java
  • Wannafly挑战赛29 白井黑子

    链接:https://ac.nowcoder.com/acm/contest/271/B
    来源:牛客网
     

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 524288K,其他语言1048576K
    64bit IO Format: %lld

    官方题解 :

    根据f(x)的定义可以发现, f(x)只有 四种质因⼦。考虑要判断两个数a,b相乘是⼀个⾃然数的 次幂,先 将a,b写成唯⼀分解的形式:

                                                  a= 2^{A2}3^{A3}5^{A5}7^{A7}     b=2^{B2}3^{B3}5^{B5}7^{B7}

    此时如果 axb是⼀个⾃然数的k次幂(k>0) ,显然有forall iin {}  left { 2,3,5,7
ight }left ( Ai+Bi 
ight )equiv 0left ( mod k
ight ) ,由于 ai leqslant 10^{18},所 以Ai,Bi 的上界不会超过60,可以⽤⼀个数组或者map记录每⼀种分解形式对应的数的个数,补集转换⼀下求出 相乘为⾃然数的k次幂的数的对数即可。

    考虑 k=0的情况需要特判,求出两个数相乘为 的数的对数即可,复杂度视实现⽅式有O(n)O(nlogn)两种。

    题目描述

    kuroko 作为常盘台唯一的空间系能力者,在每年例行的能力测试中可绝对不能让 misaka 失望哦,但是由于她的等级只是 level 4「大能力者」,在能力测试中会遇到不少困难。kuroko 是一个凡事都会尽力的好女孩,所以请你帮她算出她最多能完成多少测试吧

    对于空间系能力者测试的内容是检验对物体进行空间移动的能力,测验时一共有 n 个物品放在一条直线上,每个物品都有一个坐标 ai ,kuroko 可以选择两个物品并使用能力交换它们的位置,但是如果两个物品的坐标不满足 kuroko 的计算公式的话,她就没有办法使用能力。

    具体来说,对于坐标 ai ,其在 kuroko 的计算公式中是用参数 f(ai) 表示的。f(ai) 是 ai 各数位相乘的结果,由于 level 4「大能力者」在学园都市中也是很强大的存在,所以满足公式的条件不会太苛刻,对于两个物品 ai, aj ,如果 f(ai) x f(aj) 不能被某个自然数的 k 次幂表示 的话,那么 kuroko 就能对这两个物品使用能力。

    现在 kuroko 想知道,有多少对物品她可以对其施展能力,知道了这个后她就知道自己能完成多少测验了。

    这里认为任何自然数的 0 次幂都是 1。

    输入描述:

    第一行两个数,n, k 。
    
    第二行共 n 个数 ai 表示这 n 个物品在直线上的坐标。

    输出描述:

    输出共一个数,表示 kuroko 能对其使用能力的无序物品对数。

    示例1

    输入

    复制

    6 3
    113 10 11 1110 33 110

    输出

    复制

    2

    备注:

    2 ≤ n ≤ 105, 0 ≤ ai, k ≤ 1018
    

    my代码

    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5;
    ll n,k;
    ll a[maxn];
    ll ans=0;
    
    struct node{
        ll s[4];
        void inv(){
            for(int i=0;i<4;i++){
                s[i]=(k-s[i]%k)%k;
            }
        }
        bool operator <(const node &B) const{
            for(int i=0;i<4;i++)
                if(s[i]!=B.s[i])
                    return s[i]<B.s[i]; //内嵌比较函数
            return 0;
        }
    }nd[maxn];
    map<node,int>mp;
    ll f(ll x){
        ll an=1;
        if(x==0) return 0;
        while(x){
            an*=x%10;
            x/=10;
        }
        return an;
    }
    int main(){
        //cout << "Hello world!" << endl;
        cin>>n>>k;
        for(ll i=1;i<=n;i++){
            cin>>a[i];
            a[i]=f(a[i]);//拆位相乘
        }
        if(k==0){
            ll b=0;
            for(ll i=1;i<=n;i++)
            if(a[i]==1) b++;
            ll c=n-b;
            ans=b*c+(c-1)*c/2;
        }
        else if(k==1) ans=0;
        else{
            ll cnt=0;
            for(ll i=1;i<=n;i++){
                if(a[i]==0) continue;
                cnt++;
                while(a[i]%2==0){
                    nd[i].s[0]++;
                    a[i]/=2;
                }
                while(a[i]%3==0){
                    nd[i].s[1]++;
                    a[i]/=3;
                }
                while(a[i]%5==0){
                    nd[i].s[2]++;
                    a[i]/=5;
                }
                while(a[i]%7==0){
                    nd[i].s[3]++;
                    a[i]/=7;
                }
                nd[i].inv();
                ans+=mp[nd[i]];
                nd[i].inv();
                mp[nd[i]]++;
            }
            ans=(cnt-1)*cnt/2-ans;
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    L1-061 新胖子公式 (10 分)
    L1-060 心理阴影面积 (5 分)
    L1-059 敲笨钟 (20 分)
    Linux高性能服务器编程—进程池和线程池
    epoll系列系统调用
    18.5.2 多线程并发服务器端的实现
    10.4 基于多任务的并发服务器
    侯捷C++(complex类)
    Qt 事件机制
    C++篇49问49答
  • 原文地址:https://www.cnblogs.com/UUUUh/p/10284059.html
Copyright © 2011-2022 走看看