UVA 11728 - Alternate Task(线性筛)

题目链接

11728 - Alternate Task

分析

其实就是一个水题……由于因子和函数是积性函数,我们可以筛出所有 11000 以内的因子和函数的值,然后二分查找一下就可以了.

#include 
#include 
#include 
#include 
#include 
#include
#include 
#include 
#include 
#include 
#define fi first
#define se second
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MOD = 1e8+7;
const int MAX_P = 2e4+10;
const int maxn =1000+10;
const int MAX_V = 5e5+10;
const int maxv = 1e6+10;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;

int prime[maxn],cnt;
Pair sigma[maxn];

void init(){
    cnt =0;
    memset(prime,0,sizeof(prime));
    memset(sigma,0,sizeof(sigma));
    sigma[1].fi =1;sigma[1].se = 1;
    for(int i=2 ; iif(!prime[i]){
            prime[cnt++] = i;
            sigma[i].fi = i+1;
            sigma[i].se = i;
        }
        for(int j = 0 ; j1;
            sigma[i*prime[j]].se = i*prime[j];
            if(i % prime[j]){
                 sigma[i*prime[j]].fi = sigma[i].fi*(prime[j]+1);
            }else{
                int tmp = i;
                sigma[i*prime[j]].fi = sigma[i].fi*prime[j];
                while (tmp % prime[j] == 0)tmp/=prime[j];
                sigma[i*prime[j]].fi += sigma[tmp].fi;
                break;
            }
        }
    }
}

int main(int argc, char const *argv[]) {
    init();
    int s;
    int kase = 0;
    // for(int i=1;  i<=100 ; ++i)
    //     std::cout << sigma[i].fi << '\n';
    sort(sigma,sigma+maxn);

    while (scanf("%d", & s ) && s) {
        int pos = lower_bound(sigma,sigma+maxn,Pair(s,INF))-sigma;
        printf("Case %d: %d\n", ++kase,sigma[pos-1].fi !=s?-1: sigma[pos-1].se);
    }
    return 0;
}

你可能感兴趣的:(算法刷题)