HDU 5391 Zball in Tina Town(数论——威尔逊定理)——BestCoder Round #51(div.2)

来源:互联网 发布:免费宝贝复制软件 编辑:程序博客网 时间:2024/06/04 23:23

Zball in Tina Town

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)


Problem Description
Tina Town is a friendly place. People there care about each other.

Tina has a ball called zball. Zball is magic. It grows larger every day. On the first day, it becomes 1 time as large as its original size. On the second day,it will become 2 times as large as the size on the first day. On the n-th day,it will become n times as large as the size on the (n-1)-th day. Tina want to know its size on the (n-1)-th day modulo n.
 

Input
The first line of input contains an integer T, representing the number of cases.

The following T lines, each line contains an integer n, according to the description.
T105,2n109
 

Output
For each test case, output an integer representing the answer.
 

Sample Input
2310
 

Sample Output
20
 

Source
BestCoder Round #51 (div.2)
 

/************************************************************************/

附上该题对应的中文题

Zball in Tina Town

 
 
 Time Limit: 3000/1500 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)
问题描述
Tina Town 是一个善良友好的地方,这里的每一个人都互相关心。Tina有一个球,它的名字叫zball。zball很神奇,它会每天变大。在第一天的时候,它会变大11倍。在第二天的时候,它会变大22倍。在第nn天的时候,它会变大nn倍。zball原来的体积是11。Tina想知道,zball在第n-1n1天时的体积对nn取模是多大呢?Tina是一个蠢蠢的女孩子,当然不会算啦,所以她请你帮她算出这个答案呢。
输入描述
第一行一个正整数TT,表示数据组数接下来TT行,每行一个正整数nn,意义如题面所述T \leq 10^5,2 \leq n \leq 10^9T105,2n109
输出描述
对于每组数据,输出一个正整数,表示答案。
输入样例
2310
输出样例
20
/****************************************************/

出题人的解题思路:

1000 Zball in Tina Town

出题人:wuzhuangtai00

这题就是求 (n-1)!modn(n1)mod n

如果nn为合数,显然答案为0.

如果nn为素数,那么由威尔逊定理可得答案为 n-1n1

注意有个trick为 nn = 4.

脑到用时方恨少,说实话,看着一位位大牛们把这题A出来,我就觉得自己为何如此蠢,虽然看懂了题目是让我们求(n-1)!对n取模的结果,但是着实不知道如何着手,甚至我还查到了阶乘的近似公式(stirling公式)


然而并没有任何用处。

看了出题人的解题报告之后,我才惊呆了,居然用了数论四大定理,我只能说我学艺不精,当初貌似有看到过威尔逊定理,但是被我默默忽略了,因为百度百科关于威尔逊定理有这么一句描述的话“由于阶乘是呈爆炸增长的,其结论对于实际操作意义不大”。好吧,我醉了,还是一起来温故一下这个定理吧

( p-1)! ≡ -1 ( mod p )

即(p-1)!+1能被p整除(当且仅当p为素数)

在此先不予证明,想要看证明的可以看一下百度百科(链接),虽然表示我看得云里雾里

回到出题人的解题报告,素数的问题解决了,那我们看n为合数的情况,除了4以外,因为每一个合数都存在比它小的约数能组成该合数,所以(n-1)!必定是能够被n整除的,比如12,它能由3*4构成,所以11!必定能被12整除

而4,只有一个2,不够组成4,所以4要单独考虑。

关于上述判断素数的方法,普通的判断当然ok

for(int i=2;i*i<=n;i++)    if(n%i==0)         break;

而你用费马检测的方法也是行的

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<math.h>#include<vector>#include<map>#include<set>#include<stdlib.h>#include<cmath>#include<string>#include<algorithm>#include<iostream>#define exp 1e-10#define ll __int64using namespace std;const int N = 500005;const int inf = 1000000000;const int mod = 258280327;//快速幂ll Quick_Mod(ll a, ll b, ll mod){    ll res = 1,term = a % mod;    while(b)    {        if(b & 1) res = (res * term) % mod;        term = (term * term) % mod;        b >>= 1;    }    return res;}//费马检测bool Is_Prime(ll n){   int i;   for(i = 0;i < 5;i++)//随机次数       if(Quick_Mod(1 + rand() % (n - 1),n - 1,n) != 1)         break;   if(i == 5) return true;   return false;}int main(){    int t;    __int64 n;    scanf("%d",&t);    while(t--)    {        scanf("%I64d",&n);        if(n==4)            puts("2");        else if(Is_Prime(n))            printf("%I64d\n",n-1);        else            puts("0");    }    return 0;}
菜鸟成长记

0 0
原创粉丝点击