hdu5072 2014 Asia AnShan Regional Contest C Coprime
最后一次参加亚洲区……
题意:给出n(3 ≤ n ≤ 105)个数字,每个数ai满足1 ≤ ai ≤ 105,求有多少对(a,b,c)满足[(a, b) = (b, c) = (a, c) = 1] or [(a, b) ≠ 1 and (a, c) ≠ 1 and (b, c) ≠ 1],都互素或都不互素。
思路:如果是两个数,互素比较好求,边遍历边分解质因子,利用容斥原理即可知道前面与自己互素的有多少。left_prime[i]表示左边与自己互素的,left_no_prime[i]表示左边与自己不互素的数量,同理right表示右边的情况。
总用情况减去不合法情况即可,总共情况C(n,3),非法情况有以下几种:
对于b而言,②④即left_prime[b] * right_no_prime[b],③⑥即left_no_prime[b]*right_prime[b];
对于a而言,③⑤ 与①④,即right_prime[a] * right_no_prime[a];
对于c而言,②⑤ 与 ①⑥,即left_prime[c] * left_no_prime[c];
即可以发现这六个图每个出现了两次,故遍历一遍求出来除以2即是非法情况的数量。
代码:
加了个小优化,将100 000个数字,在init时分解质因子,每个数字只分解一次,C++ 300+ms AC
- #include <stdio.h>
- #include <iostream>
- #include <string.h>
- #include <algorithm>
- using namespace std;
- const int MAXN = ;
- long long prime[MAXN+];
- int getPrime(){
- memset(prime,,sizeof(prime));
- for(int i=;i<=MAXN;i++){
- if(!prime[i]) prime[++prime[]]=i;
- for(int j=;j<=prime[]&&prime[j]<=MAXN/i;j++){
- prime[prime[j]*i]=;
- if(i%prime[j]==) break;
- }
- }
- return prime[];
- }
- int Stack[MAXN][], s_top[MAXN];
- int arr[MAXN],num[MAXN];
- int left_prime[MAXN],left_no_prime[MAXN];
- int right_prime[MAXN],right_no_prime[MAXN];
- void factor_full_Stack(){
- for(int i = ;i <= ;i ++){
- s_top[i] = ;
- int x = i;
- for(int j = ;x != ;j ++){
- if(prime[j] * prime[j] > i){
- Stack[i][s_top[i] ++] = x;
- break;
- }
- if(x % prime[j] == ) Stack[i][s_top[i] ++] = prime[j];
- while(x % prime[j] == ) x /= prime[j];
- }
- }
- return ;
- }
- void factor(int x){
- int end = ( << s_top[x]);
- for(int i = ;i < end;i ++){
- int tmp = ;
- for(int j = ;j < s_top[x];j ++){
- if(i & ( << j)){
- tmp *= Stack[x][j];
- }
- }
- num[tmp] ++;
- }
- return ;
- }
- int cal_coprime_num(int x){
- int res = ;
- int end = ( << s_top[x]);
- for(int i = ;i < end;i ++){
- int cnt = ,tmp = ;
- for(int j = ;j < s_top[x];j ++){
- if(i & ( << j)){
- cnt ++;
- tmp *= Stack[x][j];
- }
- }
- if(cnt & ){
- res += num[tmp];
- }else{
- res -= num[tmp];
- }
- }
- return res;
- }
- void init(){
- getPrime();
- factor_full_Stack();
- }
- int main(){
- init();
- int T,n;
- scanf("%d",&T);
- while(T --){
- scanf("%d",&n);
- for(int i = ;i < n;i ++){
- scanf("%d",&arr[i]);
- }
- memset(num, , sizeof(num));
- for(int i = ;i < n;i ++){
- left_no_prime[i] = cal_coprime_num(arr[i]);
- left_prime[i] = i - left_no_prime[i];
- factor(arr[i]);
- }
- memset(num, , sizeof(num));
- for(int i = n - ;i >= ;i --){
- right_no_prime[i] = cal_coprime_num(arr[i]);
- right_prime[i] = n - i - - right_no_prime[i];
- factor(arr[i]);
- }
- long long res = (long long)n * (n-) *(long long)(n-) / ;
- long long cha = ;
- for(int i = ;i < n;i ++){
- cha += (long long) left_prime[i] * left_no_prime[i];
- cha += (long long) left_prime[i] * right_no_prime[i];
- cha += (long long) right_prime[i] * left_no_prime[i];
- cha += (long long) right_prime[i] * right_no_prime[i];
- }
- res -= cha / ;
- printf("%I64d\n",res);
- }
- return ;
- }
hdu5072 2014 Asia AnShan Regional Contest C Coprime的更多相关文章
- hdu5071 2014 Asia AnShan Regional Contest B Chat
模拟题: add的时候出现过的则不再添加 close的时候会影响到top rotate(Prior.Choose)的时候会影响到top /*============================== ...
- 2014 Asia AnShan Regional Contest --- HDU 5073 Galaxy
Galaxy Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5073 Mean: 在一条数轴上,有n颗卫星,现在你可以改变k颗 ...
- dp --- 2014 Asia AnShan Regional Contest --- HDU 5074 Hatsune Miku
Hatsune Miku Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5074 Mean: 有m种音符(note),现在要从 ...
- 2014 Asia AnShan Regional Contest --- HDU 5078 Osu!
Osu! Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5078 Mean: 略. analyse: 签到题,直接扫一遍就得答 ...
- HDU 5073 Galaxy 2014 Asia AnShan Regional Contest 规律题
推公式 #include <cstdio> #include <cmath> #include <iomanip> #include <iostream> ...
- HDU 5074 Hatsune Miku 2014 Asia AnShan Regional Contest dp(水
简单dp #include <stdio.h> #include <cstring> #include <iostream> #include <map> ...
- 2014 ACM-ICPC Asia Anshan Regional Contest(Online Version)
题目I - Osu! - HDU 5078 题目分析:最水的一道题吧,求两点间的距离和时间差值的最大比值 #include<stdio.h> #include<math.h> ...
- UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...
- UVALive 7143 Room Assignment(组合数学+DP)(2014 Asia Shanghai Regional Contest)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...
随机推荐
- vbScript常用运算符与函数
基本运算 + 数字加法及字符串连接 - 数字减法 * 数字乘法 / 数字除法 Mod 求余数 \ 求商数 & 字符串连接 ^ 次方 = 相等 <> 不相等 >= 大于或等于 ...
- SoapUI中Groovy的实用方法
1.依照上次结果判断下步是否执行: import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus myTestStep ...
- 将war包布署在本地tomcat上
1.把war包解压到..webapps目录下 2. 修改server.xml文件,在host节点中添加 <Context docBase="C:\Users\bai\Desktop\s ...
- 【LeetCode】6 - ZigZag Conversion
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- C语言实现strlen
strlen: #ifndef STRLEN_H #define STRLEN_H #include <stdio.h> // 参考微软的写法 int cat_strlen(const c ...
- 整理string类常见方法的使用说明
整理String类的Length().charAt().getChars().replace().toUpperCase().toLowerCase().trim().toCharArray()使用说 ...
- (转载)OC学习篇之---类目的概念和使用
上一篇文章介绍了OC中的@class关键字的使用,这一篇我们介绍一下,OC中的一个特有的亮点:类目 首先我们来看一下场景,如果我们现在想对一个类进行功能的扩充,我们该怎么做? 对于面向对象编程的话,首 ...
- Linux 的 screen用法
screen可以将任务挂起,即将任务放在后台,一般5个任务左右. 1.新建screen会话:直接输入screen命令或者screen -S [会话名称] 2.退出会话:按下组合键Ctrl+a并松开,此 ...
- Flex之自定义事件
1.通过dispatchEvent委托事件模式完成自定义事件: <?xml version="1.0" encoding="utf-8"?> < ...
- Codeforces Educational Codeforces Round 15 E - Analysis of Pathes in Functional Graph
E. Analysis of Pathes in Functional Graph time limit per test 2 seconds memory limit per test 512 me ...