Counting Rhyme
题目信息
题目链接
Luogu CF1884D、Codeforces 1884D
题面翻译
给定长度为 的序列 。对于 ,若不存在 使得 且 那么 是好的。
求出好的数对数量。。
题目描述
You are given an array of integers .
A pair of integers , such that , is called good, if there does not exist an integer ( ) such that is divisible by and is divisible by at the same time.
Please, find the number of good pairs.
输入格式
Each test contains multiple test cases. The first line contains the number of test cases ( ). The description of the test cases follows.
The first line of each test case contains a single integer ( ).
The second line of each test case contains integers ( ).
It is guaranteed that the sum of over all test cases does not exceed .
输出格式
For each test case, output the number of good pairs.
样例 #1
样例输入 #1
6 4 2 4 4 4 4 2 3 4 4 9 6 8 9 4 6 8 9 4 9 9 7 7 4 4 9 9 6 2 9 18 10 18 18 15 14 4 5 6 8 9 10 12 15 16 18 17 13 11 21 12 19 19 18 18 12 2 18 19 12 12 3 12 12 12 18 19 16 18 19 12
样例输出 #1
0 3 26 26 124 82
提示
In the first test case, there are no good pairs.
In the second test case, here are all the good pairs: , , and .
题目思路
因为 且 ,所以 。
假设 表示 的对数。
我们发现这个很难求,于是我们在定义一个状态:
设 表示 的个数,这个可以直接暴力 求。
于是 就行。
只需要再看 是否合法。同样可以把不合法的筛掉,即 不能是 的倍数。。
结束。
代码
#include<bits/stdc++.h> #pragma G++ optimize(2) #define int long long using namespace std; const int MAXN = 1e6+10; int mu[MAXN+10],prime[MAXN+10]; bitset<MAXN+10> is_prime; void Euler_sieve(){ mu[1] = 1; for(int i = 2;i<MAXN;i++){ if(!is_prime[i]){ prime[++prime[0]] = i; mu[i] = -1; } for(int j = 1;j<=prime[0]&&i*prime[j]<MAXN;j++){ is_prime[i*prime[j]] = 1; if(i%prime[j]==0){ mu[i*prime[j]] = 0; break; }else{ mu[i*prime[j]] = -mu[i]; } } } } int T,n,a[MAXN+10],g[MAXN+10]; int sum[MAXN+10] = {0};bitset<MAXN+10> vis,be; signed main(){ Euler_sieve(); scanf("%lld",&T); while(T--){ scanf("%lld",&n); vis.reset();be.set(); for(int i = 1;i<=n;i++) sum[i] = 0; for(int i = 1;i<=n;i++){ scanf("%lld",&a[i]); vis[a[i]] = 1; sum[a[i]]++; } int _ = vis._Find_first(); while(_<=n){ for(int i = _;i<=n;i+=_){ be[i] = 0; } _ = vis._Find_next(_); } for(int i = 1;i<=n;i++){ g[i] = 0; for(int j = i;j<=n;j+=i){ g[i] += sum[j]; } g[i] = g[i]*(g[i]-1)/2; } int ans = 0; for(int i = 1;i<=n;i++){ for(int j = 1;j*i<=n;j++){ ans += g[i*j]*mu[j]*be[i]; } } printf("%lld\n",ans); } return 0; }
tag
Codeforces
数学
、容斥原理
本文作者:gutongxing
本文链接:https://www.cnblogs.com/gutongxing/p/18233143
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步