hdu 七夕节

七夕节

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1883    Accepted Submission(s): 738
 
Problem Description
七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!" 人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6. 你想知道你的另一半吗?
 
Input
输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
 
Output
对于每组测试数据,请输出一个代表输入数据N的另一半的编号.
 
Sample Input
3
2
10
20
 
Sample Output
1
8
22
 
Author
Ignatius.L
 
Source
杭电ACM省赛集训队选拔赛之热身赛
 
Recommend
Eddy
 

分析:线性素数筛法打素数表。将n分解质因数后,直接带入求因子和的公式:

再减去本身即为所求。

PS:归纳分解质因数后的三种运算

将n分解质因素,结果如下:

a、所有整除n的数个数为:

b、所有整除n的数的和为:

c、所有小于n且与n互素的数(包括1)的个数为:

Example : n=24=233, thus  p1=2, p2=3, e1=3, e2=1
all the positive factors are:1, 2, 3, 4, 6, 8, 12, 24 (8 terms)
all the relatively prime numbers to 24 within 1~24 are:
1, 5, 7, 11, 13, 17, 19, 23 (8 terms) 

#include<cstdio>
#include<cmath>
#include<cstring>
int prime[801];
int isprime[801];
int kp;
int factor[1001];
int kf[1001];
int cnt;

void printprime() {
    int i, j, t;
    prime[kp++] = 2;
    isprime[4] = 1;
    for (i = 3; i < 800; i += 2) {
        if (isprime[i] == 0)
            prime[kp++] = i;
        for (j = 0; t = i * prime[j] < 800; ++j) {
            isprime[t] = 1;
            if (i % prime[j] == 0)
                break;
        }
    }
}

int main() {
    int i, T, n;
    double ans;
    printprime();
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        cnt = 0;
        int N = n;
        for (i = 0; i < kp && prime[i] <= sqrt(n); ++i) {
            if (n % prime[i] == 0) {
                factor[cnt] = prime[i];
                kf[cnt] = 1;
                n /= prime[i];
                while (n % prime[i] == 0) {
                    ++kf[cnt];
                    n /= prime[i];
                }
                ++cnt;
            }
        }
        if (cnt == 0) {
            printf("1\n");
            continue;
        }
        if (n != 1) {
            factor[cnt] = n;
            kf[cnt] = 1;
            cnt++;
        }
        ans = 1;
        for (i = 0; i < cnt; ++i)
            ans *= (pow(factor[i], kf[i] + 1) - 1) / (factor[i] - 1);
        printf("%.0f\n", ans - N);
    }
    return 0;
}

 

 

 

posted @ 2012-08-30 02:55  YogyKwan  阅读(586)  评论(0编辑  收藏  举报