gym 100947I (求因子)
Alex is a very clever boy, after all he is the son of the greatest watchmaker in Odin.
One day, Alex was playing with some old watches and he found n gears, each gear has ai teeth in it. Alex likes to make beautiful pairs of gears, he thinks a pair of gears is beautiful if we attach the two gears together and spin the first gear exactly one rotation, then the other gear spins an integer number of rotations. For example a pair of 8 and 4 is beautiful, whereas a pair of 8 and 5 isn't, neither is pair of 4and 8.
Now Alex is curious, he wants to know how many beautiful pairs are there. Counting is not Alex's thing, so he asked you to help him.
The first line of input contains one integer T: The number of test cases you need to process.
Each test case consists of two lines. The first line is a single integer n: the number of gears Alex has. The second line contains n space separated integers ai: the number if teeth in the ith gear.
1 ≤ n ≤ 104
2 ≤ ai ≤ 106
For each testcase print a single integer: the number of distinct pairs that satisfy the problem statement.
2
5
4 6 7 8 12
6
2 2 2 3 3 4
3
7
note that we consider two pair distinct when they differ by at least one gear.
In the first sample the pairs are: (4,8) , (4,12) , (6,12)
题意:
如果两个数是倍数关系,那么他们就是beautiful,问有多少对beautiful。
思路:
对于一个数,只求他的每个因子在序列中有几个就可以了,这样就不会重复,注意要先排序,不然有些会计算不到。
代码:
/** @xigua */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include<climits> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 1e6 + 5; const int mod = 1e9 + 7; const int INF = 1e8 + 5; const ll inf = 1e15 + 5; const db eps = 1e-9; int vis[maxn]; int a[maxn]; void solve() { memset(vis, 0,sizeof(vis)); int n; cin >> n; ll ans = 0; for (int i = 1; i <= n; i++) { scanf("%d", a + i); } sort(a+1, a+1+n); for (int i = 1; i <= n; i++) { int x = a[i]; for (int j = 1; j * j <= x; j++) { if (x % j == 0) { //是因子 ans += vis[j]; // 看该因子出现过几次 int xx = x / j; if (xx != j) { ans += vis[xx]; //另一个不同因子,因为因子是成对出现的 } } } vis[x]++; //先计算后标记 } cout << ans << endl; } int main() { //cin.sync_with_stdio(false); //freopen("isharp.in", "r", stdin); //freopen("isharp.out", "w", stdout); int t = 1; cin >> t; while (t--) { solve(); } return 0; }