hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)

Deciphering Password

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2357    Accepted Submission(s):
670

Problem Description

Xiaoming has just come up with a new way for
encryption, by calculating the key from a publicly viewable number in the
following way:
Let the public key N = AB, where 1 <= A, B <=
1000000, and a0, a1, a2, …, ak-1 be
the factors of N, then the private key M is calculated by summing the cube of
number of factors of all ais. For example, if A is 2 and B is 3, then N =
AB = 8, a0 = 1, a1 = 2, a2 = 4,
a3 = 8, so the value of M is 1 + 8 + 27 + 64 = 100.
However,
contrary to what Xiaoming believes, this encryption scheme is extremely
vulnerable. Can you write a program to prove it?

Input

There are multiple test cases in the input file. Each
test case starts with two integers A, and B. (1 <= A, B <= 1000000). Input
ends with End-of-File.
Note: There are about 50000 test cases in the input
file. Please optimize your algorithm to ensure that it can finish within the
given time limit.

Output

For each test case, output the value of M (mod 10007)
in the format as indicated in the sample output.

Sample Input

2 2
1 1
4 7

Sample Output

Case 1: 36 Case 2: 1 Case 3: 4393

翻译:输入a和b,n=a^b,求n的因子有哪些,这些因子又有多少个因子数,对于这些因子数的立方和累加

唯一分解定理

定义:任何一个数可以表示成 素数的次方 的乘积

分解公式: 

积性函数

对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数

素数的之间互质,素数的幂次方也互质

对于求因子个数,也是积性函数

素数的n次方有(n+1)个因子,并且这些因子的因子个数从1到n+1递增,这就可以套用1到n的立方和公式

比如3^4=81,因子有1,3,9,27,81

1-1

3-1,3

9-1,3,9

27-1,3,9,27

81-1,3,9,27,81

AC代码:

注:这段代码比较悬,用c++提交WA,用g++提交能AC,中间有一句避免多次循环找大素数没有加上的话,c++提交WA,g++提交TLE

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<vector>
#include<iostream>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
#define ll long long
const int p=10007;
const int maxx=1e6+5;
ll a,b;
int prime[maxx];
bool vis[maxx];
int cnt;
void init()///欧拉筛
{
    cnt=0;
    memset(vis,true,sizeof(vis));
    vis[0]=vis[1]=false;
    for(int i=2;i<=maxx;i++)
    {
        if(vis[i])
            prime[cnt++]=i;
        for(int j=0;j<cnt && prime[j]*i<=maxx;j++)
        {
            vis[ i*prime[j] ]=false;
            if( i%prime[j]==0 ) break;///prime[j]必定是prime[j]*i和i的最小质因子
        }
    }
}
ll sum(ll n)///立方和公式
{
   return ( (n*n+n)/2 )%p * ( (n*n+n)/2 )%p;
}

int main()
{
    init();
    int x=0;
    while(scanf("%lld%lld",&a,&b)!=EOF)
    {
        ll ans=1;
        if(vis[a])//a是素数,则直接求,节省时间
            ans=sum(1+b);
        else
        {//prime[i]*prime[i]<=a;不加就会超时,大素数的因子一般只有一个,没必要一个一个找,也可以改成!vis[a],都是避免多次循环找大素数
            for(int i=0; i<cnt && prime[i]*prime[i]<=a; i++)
            {
                int num=0;
                if(a==1) break;
                while(a%prime[i]==0)
                {
                    a=a/prime[i];
                    num++;
                }
                if(num!=0)
                {
                    ans*=sum(num*b+1);//积性函数
                    ans%=p;
                }
            }
            if(a!=1)///应对大素数的情况
            {
                ans*=sum(b+1);
                ans%=p;
            }
        }
        printf("Case %d: %lld\n",++x,ans%p);
    }
    return 0;
}
/*
手撸36=2^2 * 3^2  ans=(1^3 + 2^3 +3^3)^2=1296
36的因子有    1  2  3  4  6  9  12  18  36
对应的因子数  1  2  2  3  4  3  6   6   9
累加后也是1296
*/

Deciphering Password

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2357    Accepted Submission(s):
670

Problem Description

Xiaoming has just come up with a new way for
encryption, by calculating the key from a publicly viewable number in the
following way:
Let the public key N = AB, where 1 <= A, B <=
1000000, and a0, a1, a2, …, ak-1 be
the factors of N, then the private key M is calculated by summing the cube of
number of factors of all ais. For example, if A is 2 and B is 3, then N =
AB = 8, a0 = 1, a1 = 2, a2 = 4,
a3 = 8, so the value of M is 1 + 8 + 27 + 64 = 100.
However,
contrary to what Xiaoming believes, this encryption scheme is extremely
vulnerable. Can you write a program to prove it?

Input

There are multiple test cases in the input file. Each
test case starts with two integers A, and B. (1 <= A, B <= 1000000). Input
ends with End-of-File.
Note: There are about 50000 test cases in the input
file. Please optimize your algorithm to ensure that it can finish within the
given time limit.

Output

For each test case, output the value of M (mod 10007)
in the format as indicated in the sample output.

Sample Input

2 2
1 1
4 7

Sample Output

Case 1: 36
Case 2: 1
Case 3: 4393

原文地址:https://www.cnblogs.com/shoulinniao/p/10356459.html

时间: 2024-10-06 05:21:03

hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)的相关文章

2018南京icpc-J-Prime Game (欧拉筛+唯一分解定理)

题意:给定n个数ai(n<=1e6,ai<=1e6),定义,并且fac(l,r)为mul(l,r)的不同质因数的个数,求 思路:可以先用欧拉筛求出1e6以内的所有质数,然后对所有ai判断,如果ai不是质数就利用唯一分解定理计算其所有质因数.然后按照顺序依次计算每个质因子的贡献.假设n=5,对质因子2,依次记录它在数组出现的下标,如果它在2.4下标出现了,那么它的贡献即为所有包含2或4的区间个数,逆向计算,即所有区间个数-不包含2和4的区间个数,即 n(n+1)/2-m1(m1+1)/2-m2(

hdu3826-Squarefree number-(欧拉筛+唯一分解定理)

Squarefree number Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3691    Accepted Submission(s): 971 Problem Description In mathematics, a squarefree number is one which is divisible by no per

线性筛及其扩展-积性函数

线性筛 埃氏筛 对于每个数x,枚举其倍数,将kx筛去. 在埃氏筛过程中,每个数都会被筛掉多次,且对于每个数x,枚举其倍数的次数为\(\frac{n}{x}\) 故埃氏筛的时间复杂度为\(\sum_{i=1}^{n}\)\(\frac{n}{i}\)=n\(\sum_{i=1}^{n}\)\(\frac{1}{i}\)=\(n ln(n)\) 欧拉筛 在埃氏筛中,每个数会被筛掉多次,想要进一步下降复杂度,我们要求每个数只会被筛一次. 要想将多种筛去x的方法固定(唯一).我们就要采用一种方法-"最小

hdu4497-GCD and LCM-(欧拉筛+唯一分解定理+组合数)

GCD and LCM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3409    Accepted Submission(s): 1503 Problem Description Given two positive integers G and L, could you tell me how many solutions of

noip复习——线性筛(欧拉筛)

整数的唯一分解定理: \(\forall A\in \mathbb {N} ,\,A>1\quad \exists \prod _{i=1}^{s}p_{i}^{a_{i}}=A\),其中\({\displaystyle p_{1}<p_{2}<p_{3}<\cdots <p_{s}}\)而且 \(p_{i}\)是一个质数, \(a_{i}\in \mathbb {Z} ^{+}\)(摘自维基百科) 欧拉筛通过使每个整数只会被它的最小质因子筛到来保证时间复杂度,可以用来筛质数

欧拉筛素数+求欧拉函数

线性筛法 prime记录素数,num_prime素数下标 它们保证每个合数只会被它的最小质因数筛去 a[0]=a[1]=1; for(int i=2;i<=n;i++) { if(!a[i]) prime[num_prime++]=i; for(int j=0;j<num_prime&&i*prime[j]<=n;j++) { a[i*prime[j]]=1; if(!(i%prime[j])) break; } } } 欧拉函数 是 积性函数:对于任意互质的整数a和b有

素数筛&amp;&amp;欧拉筛 BZOJ2818 Gcd BZOJ2190 [SDOI2008]仪仗队

折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体的解释看的迷迷糊糊,特别是欧拉函数的求解 http://blog.csdn.net/lerenceray/article/details/12420725 代码如下 1 void ES(){ 2 for(int i=2;i<n;i++){ 3 if (!pd[i]){ 4 prime[++top]=

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数: #include<cstdio> #define maxn 10000000+10 using namespace std; int n,prime[5000001],num_prime=0,m; bool if_prime[maxn]; void euler(int limit) { for(int i=2;i<=limit;i++) { if(!if_prime[i]) prime[++num_prime]=i; for(int j=1;prime[j]*i<=l

欧拉筛(线性筛)

素数筛,就是按照顺序把合数踢掉,剩下的是素数. 欧拉筛是一种O(n)求素数的筛法.他避免了埃拉特斯特尼筛法对同一数的多次筛除. 欧拉筛的原理是只通过数的最小质因数筛数. 先上代码: #include <cstdio> using namespace std; const int maxn=10000000; int n, m, prime[maxn], isnt_prime[maxn], tot; void get_prime(int n){ isnt_prime[0]=isnt_prime[