2014 ACM Regional hdu 5072

ACM退役两年了, 没想到今年机缘巧合能去鞍山参加Regional了。 记得第一次参加Regional的时候那个心情很激动,激动的很难描述出来。而这次参加Regional一点压力都木有,感觉比参加省赛都轻松,甚至就像是在做练习赛似的。由于本来水平就不高,又隔了两年,所以毫无悬念地拿了个铜牌。

比赛时候C题基本已经想到了解法,由于时间的原因,没能过掉。

C题现在在hdu的5072题。

题意: 给出n个数(n<100000), 每个数都不大于100000,数字不会有重复。现在随意抽出3个,问三个彼此互质 或者 三个彼此不互质的数目有多少。

思路: 这道题的原型是同色三角形, 可能现场很多队伍都知道这个模型, 所以这道题当时过的队伍还是挺多的。

这道题反着想,就是三个数中只有一对互质 或者只有两对互质的个数。

研究后发现 对于每个数字求出与其不互质的个数k   那么  sum ( k*(n-1-k) )/2 就是相反的数目, 所以最终的答案就是 C(n,3) -  sum ( k*(n-1-k) )/2.

现在依然存在一个问题就是如何求出每个数的不互质数的个数,这个其实用容斥原理。 对于数字 a ,求出a的所有素因子, 然后枚举素因子可以构成的所有数字(构成数的过程中素因子用的个数不能超过1) w,

求出原先数组中能整出w的个数。 如果w的素因子个数为奇数就加, 偶数就减。 这就是容斥的过程。

现在还是存在一个问题, 如何快速算出原先数组中能整出w的个数。 首先对原先数据中的每个数字a, 求出所有的素因子, 然后枚举素因子可以构成的所有数字(构成数的过程中素因子用的个数不能超过1),

对于每一个枚举的数统计加1. 这样就能提前预处理出来。

算法的整体复杂度为 O(n*64*6);

AC代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
#include <iostream>
using namespace std;

const int N = 200500;
typedef long long LL;

int p[N];
int num;
bool in[N];
int a[N];
int n;
int nn[N];

void get_prime()
{
    num = 0;
    for(int i=2; i<N; i++)
    {
        if(!in[i])
        {
            p[num++] = i;
            for(int j=i; j<N; j+=i)
            {
                in[j] = true;
            }
        }
    }
}

void init()
{
    memset(nn, 0, sizeof(nn));
    int cnt = 0;
    int ele[100];
    scanf("%d", &n);
    int temp = 0;
    for(int i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        temp = a[i];
        cnt = 0;
        for(int  j=0; p[j]*p[j] <= temp; j++)
        {
            if(temp % p[j] == 0)
            {
                ele[cnt++] = p[j];
                while(temp%p[j] == 0)
                    temp /= p[j];
            }
        }
        if(temp != 1)
        {
            ele[cnt++] = temp;
        }
        for(int j=1; j<(1<<cnt); j++)
        {
            temp = 1;
            for(int k=0; k<cnt; k++)
            {
                if( (1<<k) & j )
                {
                    temp *= ele[k];
                }
            }
            nn[temp]++;
        }
    }
}

void solve()
{
    LL ans = n;
    LL ss = 0;
    int temp;
    ans = ans*(n-1)*(n-2)/6;
    for(int i=0; i<n; i++)
    {
        int cnt = 0;
        int ele[100];
        temp = a[i];
        cnt = 0;
        for(int  j=0; p[j]*p[j] <= temp; j++)
        {
            if(temp % p[j] == 0)
            {
                ele[cnt++] = p[j];
                while(temp%p[j] == 0)
                    temp /= p[j];
            }
        }
        if(temp != 1)
        {
            ele[cnt++] = temp;
        }
        LL ret = 0;
        for(int j=1; j<(1<<cnt); j++)
        {
            temp = 1;
            int hh = 0;
            for(int k=0; k<cnt; k++)
            {
                if( (1<<k) & j )
                {
                    temp *= ele[k];
                    hh++;
                }
            }
            if(hh%2 == 1) ret += nn[temp];
            else ret -= nn[temp];
        }
        if(ret == 0) continue;
        ss = ss + (ret-1)*(n-ret);
       // cout<<i<<"  "<<ret<<"  "<<ss<<endl;
    }
    cout<<ans - ss/2<<endl;
}

int main()
{
    get_prime();
    int t;
    scanf("%d", &t);
    while(t--)
    {
        init();
        solve();
    }
    return 0;
}

时间: 2025-01-16 06:01:24

2014 ACM Regional hdu 5072的相关文章

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ

hdu 5008(2014 ACM/ICPC Asia Regional Xi&#39;an Online ) Boring String Problem(后缀数组&amp;二分)

Boring String Problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 219    Accepted Submission(s): 45 Problem Description In this problem, you are given a string s and q queries. For each que

2014 ACM/ICPC Asia Regional Xi&#39;an Online(HDU 5007 ~ HDU 5017)

题目链接 A题:(字符串查找,水题) 题意 :输入字符串,如果字符串中包含“ Apple”, “iPhone”, “iPod”, “iPad” 就输出 “MAI MAI MAI!”,如果出现 “Sony” 就输出“SONY DAFA IS GOOD!” ,大小写敏感. 思路 : 字符串查找,水题. 1 #include <string.h> 2 #include <stdio.h> 3 #include <iostream> 4 5 using namespace st

HDU 5014 Number Sequence 贪心 2014 ACM/ICPC Asia Regional Xi&#39;an Online

尽可能凑2^x-1 #include <cstdio> #include <cstring> const int N = 100005; int a[N], p[N]; int init(int x) { int cnt = 0; while(x > 1) { x /= 2; cnt ++; } return cnt + 1; } int main() { int n; while(~scanf("%d", &n)){ for(int i = 0;

HDU 5010 Get the Nut(2014 ACM/ICPC Asia Regional Xi&#39;an Online)

思路:广搜, 因为空格加上动物最多只有32个那么对这32个进行编号,就能可以用一个数字来表示状态了,因为只有 ‘P’   'S' 'M' '.' 那么就可以用4进制刚好可以用64位表示. 接下去每次就是模拟了. 注意:  ‘S’ 不是只有一个. 一个东西如果不是'P'在动的话要先判断周围有没有‘P’,有的话要先吃掉      'P'在动的时候如果一个位置周围有多个东西,都要吃掉. #include<iostream> #include<cstdio> #include<alg

hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi&#39;an Online)

Mart Master II Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 675    Accepted Submission(s): 237 Problem Description Trader Dogy lives in city S, which consists of n districts. There are n - 1

2014 ACM/ICPC Asia Regional Xi&#39;an Online 233 Matrix,hdu 5015

比赛的时候若是这题过了就进前50 刚开始的时候大家的思路都以为是找规律的题目,于是再推公式,此外还发现类似于杨辉三角.于是又去套杨辉三角的通项去求. 于是TLE了无数次.(每次取范围的最大值也要3s多). 对于明显的矩阵样子,其实可以转化为矩阵的运算,每一行的转移.就是对一个转移矩阵的幂运算.然后再用快速矩阵幂即可. A: 10 0 0 1 10 1 0 1 10 1 1 1 0  0  0 1 B: 23 0 0 3 C=A^M  *B,ans=C[N] 教训:对于时间限制,即便是最大数据也要

HDU 5000 2014 ACM/ICPC Asia Regional Anshan Online DP

Clone Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total Submission(s) : 8   Accepted Submission(s) : 5 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description After eating food from Chernobyl,

poj 5024&amp;&amp;&amp;2014 ACM/ICPC Asia Regional Guangzhou Online 1003(预处理)

http://acm.hdu.edu.cn/showproblem.php?pid=5024 分析:预处理每个点在八个方向的射线长度,再枚举八种L形状的路,取最大值. 注意题意是求一条最长路,要么一条直线,要么只有一个90角,即L型.其实直线就是L形的一个方向长度为0. 代码: #include<iostream> #include<map> #include<cstdio> #include<string> #include<cstring>