问题 H: A Partial Order Relation
时间限制: 1 Sec 内存限制: 128 MB
提交: 93 解决: 24
[提交] [状态] [讨论版] [命题人:admin]
题目描述
In mathematics, a partial order set formalizes and generalizes the intuitive concept of an ordering, sequencing, or arrangement of elements of a set. It is a binary relation indicating that, for certain pairs of elements in a set, one of the elements precedes the other in the ordering but not every pair is comparable. For example, the divisors of 120 form a partial order set. Let the binary relation ≺ be divisibility relation. So, 120 ≺ 24 and 120 ≺ 40 but there is no such relation between 24 and 40. ≺ is a transitive relation such that 120 ≺ 40 and 40 ≺ 8 imply 120 ≺ 8.
Let’s define a more restrictive binary relation called greatest divisibility relation . Given a number a. Let div(a) be a set of all divisors of a minus a. Then we define a b if b is a divisor of a but b cannot divide any other numbers in div(a). For example, div(30) = {1, 2, 3, 5, 6, 10, 15}. 30
6 because 6 cannot be used to divide other elements in the set.
Given a number, you can construct relation among the its divisors as in Fig. 1 for 120. The depth of the graph from root node (120) to the terminal node (always 1) is 5 and
the number of edges are 28. Given an integer, please compute the number of edges in its relation graph.
输入
The input data begins with a number n (n <= 100), which is the number of test cases. Each test case contains only a positive integer r, where 1 < r < 240 . r is the number to build relation.
输出
For each test case, please print the number of edges in its divisibility relation.
样例输入
2 6 120
样例输出
4 28
唉,这个题想的过于麻烦了,现在想写一篇博客也算是重新想一下思路,一开始很快就发现就是每个因子然后分解成唯一素数的个数的和,结果超时很悲伤,复杂度没算好,后来其实不用再去求,只需要对n进行质数分解,然后求每个质数对答案的贡献就可以了如:120 = 2^3*3*5 2有三个 3有一个 5有一个 然后我们考虑2对答案的贡献 首先2有2 4 8 这三个数都可以对答案贡献剩下的3 和 5 出现的次数随便就可以了也就是(1+1)*(1+1) 为什么加1呢因为也可能出现0次,所以最后质因数2对答案的贡献为3*2*2=12,3的贡献为1*4*2=8,5的贡献为1*4*2=8加起来就是最后答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+10;
void solve(){
ll n;
scanf("%lld",&n);
ll a[N],cnt,b[N],ans;
cnt = 0;
ll temp = (ll)((double)sqrt(n)+1);
ll now = n;
for(int i = 2;i <= temp;i++)
{
if(now%i==0)
{
a[++cnt] = i;
b[cnt] = 0;
while(now%i==0)
{
++b[cnt];
now/=i;
}
}
}
if(now != 1)
{
a[++cnt] = now;
b[cnt] = 1;
}
ans = 0;
for(int i = 1;i <= cnt;i++)
{
ll res = 1;
for(int j = 1;j <= cnt;j++)
{
if(i==j)
continue;
res*=(b[j]+1);
}
ans += res*(b[i]);
// cout<<ans<<endl;
}
printf("%lld\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}