LightOJ - 1054 - Efficient Pseudo Code

先上题目

1054 - Efficient Pseudo Code
Time Limit: 1 second(s) Memory Limit: 32 MB

Sometimes it's quite useful to write pseudo codes for problems. Actually you can write the necessary steps to solve a particular problem. In this problem you are given a pseudo code to solve a problem and you have to implement the pseudo code efficiently. Simple! Isn't it? :)

pseudo code

{

    take two integers n and m

    let p = n ^ m (n to the power m)

    let sum = summation of all the divisors of p

    let result = sum MODULO 1000,000,007

}

Now given n and m you have to find the desired result from the pseudo code. For example if n = 12 and m = 2. Then if we follow the pseudo code, we get

pseudo code

{

    take two integers n and m

    so, n = 12 and m = 2

    let p = n ^ m (n to the power m)

    so, p = 144

    let sum = summation of all the divisors of p

    so, sum = 403, since the divisors of p are 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 36, 48, 72, 144

    let result = sum MODULO 1000,000,007

    so, result = 403

}

Input

Input starts with an integer T (≤ 5000), denoting the number of test cases.

Each test case will contain two integers, n (1 ≤ n) and m (0 ≤ m). Each of n and m will be fit into a 32 bit signed integer.

Output

For each case of input you have to print the case number and the result according to the pseudo code.

Sample Input

Output for Sample Input

3

12 2

12 1

36 2

Case 1: 403

Case 2: 28

Case 3: 3751

  这一题的题意很简单,就是给你2个数n,m求n的m次幂的因子和是多少,当然,结果要模1000000007。这一题的要求其实有两个,一是不超时,二是得到正确的答案,则用普通的pow函数配合求因子明显不行。

  首先,因为数字很大,如果先pow在求模明显早溢出了,其次,太大的数字求因子和明显慢得像蜗牛。所以这一题需要自己写一个快速幂,同时要知道一件事就是我们不需要一开始就算出pow(n,m)出来,由素数唯一分解定理可以得到,pow(n,m)的分解出来的素数种类和n分解出来的种类是一样的只是数目上是n的各个素数的数目的m倍,所以我们可以先求出n的素数,然后每一个的含有数目都乘上m即可,然后就是求因子和了。求因子和需要求每一个素数的p^αi这一个等比数列,然后根据乘法原理求出结果,就是因子和这里可以很好地理解,每一个素数出现有0~p^αi这么多种状态,它们和其他素数的不同状态组合起来就得到所有的结果了。这里有很多方法,师兄的代码是用逆元来解,但是暂时我还不懂逆元怎样用,而且师兄说过这种方法有局限,因此这里我使用的是另一种解法,就是二分求等比数列。分析如下图

 

  代码可以对两种情况进行完全分开的写求值过程,而不是偶数时前半部分化为奇数情况调用,前者大概会快一点。(= =反正两种我都试过了)

上代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <math.h>
  4 #define MOD 1000000007
  5 #define LL long long
  6 #define MAX (1<<16)+10
  7 using namespace std;
  8 
  9 LL pri[MAX];
 10 int tot;
 11 bool mark[MAX];
 12 
 13 void dedeal()
 14 {
 15     LL i,n,j;
 16     n=MAX-10;
 17     memset(pri,0,sizeof(pri));
 18     memset(mark,0,sizeof(mark));
 19     for(i=2;i<=n;i++)
 20     {
 21         if(!mark[i])
 22         {
 23             pri[tot++]=i;
 24             for(j=i*i;j<=n;j+=i)
 25             {
 26                 mark[j]=1;
 27             }
 28         }
 29     }
 30 }
 31 
 32 LL FastMod(LL a,LL q)
 33 {
 34     if(q==0) return 1;
 35     LL t=FastMod(a,q>>1);
 36     t=t%MOD;
 37     t=t*t%MOD;
 38     if(q&1) t=t*a%MOD;
 39     return t;
 40 }
 41 
 42 /*
 43 LL FastMod(LL a,LL q)
 44 {
 45     LL k,r;
 46     if(!q) return 1;
 47     k=1;
 48     r=a%MOD;
 49     while(q>1)
 50     {
 51         if(q&1) k=k*r%MOD;
 52         r=r*r%MOD;
 53         q>>=1;
 54     }
 55     return r*k%MOD;
 56 }
 57 */
 58 LL f(LL a,LL q)
 59 {
 60     if(q==0) return 1;
 61     if(q&1) return (f(a,q>>1)%MOD*(1+FastMod(a,(q+1)>>1)))%MOD;
 62     return (f(a,q-1)%MOD+FastMod(a,q))%MOD;
 63 }
 64 
 65 LL fs(LL n,LL M)
 66 {
 67     LL i,m,sum,amo;
 68     i=0;
 69     m=sqrt(n);
 70     sum=1;
 71     for(i=0;i<tot && pri[i]<=m;i++)
 72     {
 73         if(n%pri[i]==0)
 74         {
 75             amo=0;
 76             //printf("%lld ",pri[i]);
 77             while(n%pri[i]==0) {n/=pri[i];amo++;}
 78             sum=sum*f(pri[i],(amo*M))%MOD;
 79         }
 80         if(n==1) break;
 81     }
 82     if(n>1) sum=sum*f(n,M)%MOD;
 83     return sum%MOD;
 84 }
 85 
 86 int main()
 87 {
 88     int t,i;
 89     LL n,m,sum;
 90     //freopen("data.txt","r",stdin);
 91     dedeal();
 92     scanf("%d",&t);
 93     for(i=1;i<=t;i++)
 94     {
 95         scanf("%lld %lld",&n,&m);
 96         sum=fs(n,m);
 97         printf("Case %d: %lld\n",i,sum%MOD);
 98     }
 99     return 0;
100 }
1054

 

 

 

 

 

posted @ 2013-07-31 21:02  海拉鲁的林克  阅读(470)  评论(0编辑  收藏  举报