hdu 1014 Uniform Generator 数论
摘取于http://blog.csdn.net/kenden23/article/details/37519883;
找到規律之后本題就是水題了,不過找規律也不太容易的,證明這個規律成立更加不容易。
本題就是求step和mod如果GCD(最大公約數位1)那么就是Good Choice,否則為Bad Choice
為什么這個結論成立呢?
因為當GCD(step, mod) == 1的時候,那么第一次得到序列:x0, x0 + step, x0 + step…… 那么mod之后,必然下一次重復出現比x0大的數必然是x0+1,為什么呢?
因為(x0 + n*step) % mod; 且不需要考慮x0 % mod的值為多少,因為我們想知道第一次比x0大的數是多少,那么就看n*step%mod會是多少了,因為GCD(step, mod) == 1,那么n*step%mod必然是等于1,故此第一次重復出現比x0大的數必然是x0+1,那么第二次出現比x0大的數必然是x0+2,以此類推,就可得到必然會出現所有0到mod-1的數,然后才會重復出現x0.
當GCD(step, mod) != 1的時候,可以推出肯定跨過某些數了,這里不推了。
然后可以擴展這個結論,比如如果使用函數 x(n) = (x(n-1) * a + b)%mod;增加了乘法因子a,和步長b了;
那么如果是Good Choice,就必然需要GCD(a, mod) == 1,而且GCD(b, mod) == 1;
(另外的證明)
對于mod n域中的任意數a,若有gcd(m,n)=1,則m為該域的生成元,使得a+km可以為域中任意數.
證明十分簡單,若gcd(m,n)=1,則lcm(m,n)=m*n,則對于a的mod n運算,需要n次的計算才能回到a,期間必遍歷該域中所有數!
#include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> using namespace std; #define ll __int64 #define mod 1000000007 int scan() {int res = 0 , ch ;while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) ){if( ch == EOF ) return 1 << 30 ;}res = ch - '0' ;while( ( ch = getchar() ) >= '0' && ch <= '9' )res = res * 10 + ( ch - '0' ) ;return res ; } int gcd(int x,int y) {return x%y?gcd(y,x%y):y; } int main() {int x,y,z,i,t;while(~scanf("%d%d",&x,&y)){printf("%10d%10d",x,y);if(gcd(x,y)==1)printf(" Good Choice\n");//4個空格,pe多次elseprintf(" Bad Choice\n");printf("\n");}return 0; }
轉載于:https://www.cnblogs.com/jhz033/p/5330326.html
總結
以上是生活随笔為你收集整理的hdu 1014 Uniform Generator 数论的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eclipse安装birt插件
- 下一篇: time时间格式输出转换