题意:

输入一个正整数n(n<=1e18),输出所有的i相乘并对n取余所得的值。(gcd(i,n)==1,1<=i<=n)

题解:

比赛的时候花了一个小时找规律,楞是没找到,无语死了。。比赛后看到规律,想直接用Pollard_rho算法和Miller_Rabin算法找出所有因子求解,无限TLE,别人都能200MS过,为毛我写的算法就这么挫呢。最后只要退一步用Miller_Rabin算法+线性筛了。

规律:将n分解分所有质因子相乘,质因子2个数为a,其余质因子个数为b,ans=(a==0?a:a-1)+b;当ans<2时结果为n-1,否则结果为1.

Miller_Rabin算法:判断n是否为素数,

Pollard rhos算法:求n的所有因子。

详细的可以看:算法集锦(特殊模板集)

我们将对2取余,得到a和剩余的数k,然后判断k是否为1,为1的时候b=0。然后判断是否是素数,素数的时候b=1;当k不是素数的时候只有k=c^m(c为素数,m>=2)时b=1,其余情况b>=2,则结果必定为1。怎么判断k=c^m?m=2的时候直接开方判断,m>2则枚举1e6以内的所有素数判断即可。

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
using namespace std;
typedef __int64 LL;
const LL NUM=20;//运算次数,Miller_Rabin算法为概率运算,误判率为2^(-NUM);
const int maxn=1e6+10;
int prime[maxn],c[maxn],tot;
LL t,f[1000];
LL mul_mod(LL a,LL b,LL n)//求a*b%n,由于a和b太大,需要用进位乘法
{a=a%n;b=b%n;LL s=0;while(b){if(b&1)s=(s+a)%n;a=(a<<1)%n;b=b>>1;}return s;
}
LL pow_mod(LL a,LL b,LL n)//求a^b%n
{a=a%n;LL s=1;while(b){if(b&1)s=mul_mod(s,a,n);a=mul_mod(a,a,n);b=b>>1;}return s;
}
bool check(LL a,LL n,LL r,LL s)
{LL ans,p,i;ans=pow_mod(a,r,n);p=ans;for(i=1;i<=s;i++){ans=mul_mod(ans,ans,n);if(ans==1&&p!=1&&p!=n-1)return true;p=ans;}if(ans!=1)return true;return false;
}
bool Miller_Rabin(LL n)//Miller_Rabin算法,判断n是否为素数
{if(n<2)return false;if(n==2)return true;if(!(n&1))return false;LL i,r,s,a;r=n-1;s=0;while(!(r&1)){r=r>>1;s++;}for(i=0;i<NUM;i++){a=rand()%(n-1)+1;if(check(a,n,r,s))return false;}return true;
}
LL gcd(LL a,LL b)
{return b==0?a:gcd(b,a%b);
}
LL Pollard_rho(LL n,LL c)//Pollard_rho算法,找出n的因子
{LL i=1,j,k=2,x,y,d,p;x=rand()%n;y=x;while(true){i++;x=(mul_mod(x,x,n)+c)%n;if(y==x)return n;if(y>x)p=y-x;else p=x-y;d=gcd(p,n);if(d!=1&&d!=n)return d;if(i==k){y=x;k+=k;}}
}
void find(LL n)//找出n的所有因子
{if(Miller_Rabin(n)){f[t++]=n;//保存所有因子return;}LL p=n;while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);//由于p必定为合数,所以通过多次求解必定能求得答案find(p);find(n/p);
}
void init()//预处理,找出所有1e7以内的素数,以减少查找1e14范围数的因子的时间
{           //现行筛素数的方法,时间复杂度为O(n)memset(c,false,sizeof(c));int i,j;tot=0;for(i=2;i<=1e6;i++){if(!c[i])prime[tot++]=i;for(j=0;j<tot;j++){if(i*prime[j]>1e6)break;c[i*prime[j]]=true;if(i%prime[j]==0)break;}}//printf("%d\n",tot);//for(i=0;i<20;i++)//    printf("prime[%d]:%d\n",i,prime[i]);
}
bool judge(LL n)
{int i,j,k;for(i=0;i<tot;i++){if(n%prime[i]==0){while(n%prime[i]==0)n=n/prime[i];if(n==1)return true;return false;}}return false;
}
int main()
{//freopen("D:\\in.txt","r",stdin);//freopen("C:\\Documents and Settings\\Administrator\\桌面\\false.txt","w",stdout);srand(time(NULL));//随机数设定种子init();LL n;while(cin>>n){if(n==-1)break;if(n==1){cout<<0<<endl;continue;}/*t=0;find(n);sort(f,f+t);LL i,j,k=0,ans=0;if(f[0]==2)k++;else ans++;for(i=1;i<t;i++){if(f[i]==2)k++;if(f[i]!=f[i-1])ans++;}if(k>=1)ans+=k-1;//cout<<n<<":";if(ans<2)cout<<n-1<<endl;else cout<<1<<endl;*/LL i,j,k,ans=0;k=n;while(k%2==0){k=k/2;ans++;}if(ans>=1)ans--;if(k!=1){if(Miller_Rabin(k))ans++;else{i=(LL)sqrt(k+0.5);if(i*i==k&&Miller_Rabin(i)||judge(k))ans++;else ans+=2;}}if(ans<2)cout<<n-1<<endl;else cout<<1<<endl;}return 0;
}

hdu 4910 Problem about GCD 找规律+Miller_Rabin算法+线性筛相关推荐

  1. HDU 5703 Desert 水题 找规律

    HDU 5703 Desert 水题 找规律 已知有n个单位的水,问有几种方式把这些水喝完,每天至少喝1个单位的水,而且每天喝的水的单位为整数.看上去挺复杂要跑循环,但其实上,列举几种情况之后就会发现 ...

  2. hdu 小t的游戏(找规律)

    小t的游戏 Problem Description 小t有点神经质,喜欢发明一些稀奇古怪的游戏,比如说左手和右手打架就是他发明的. 这个周末,小t又发明了一个有趣的硬币游戏:小t手里有6枚硬币,他把硬 ...

  3. Problem D. Euler Function HDU - 6322(欧拉数,找规律)

    题目链接,继续嗖~~~~ 首先理解一下这些名词的意思: 欧拉数:比他小的数中,与他互质数的个数.(特别的a(1)=1) 互质数:两数除了1以外没有别的公约数. 合数:合数中除了能被1和本身整除外,还能 ...

  4. hdu 1005 1021 递归超限 找规律 // 只要看题中n较大都是有规律的

    因为n>1000000000所以用递归 数组超限, 由递归函数f(n)=(A*f(n-1)+B*f(n-2))%7; 因为是除7的余数 因次一共有7*7=49种情况, 以后的值都和之前的对应相等 ...

  5. hdu 1165 坑爹找规律题

    http://acm.hdu.edu.cn/showproblem.php?pid=1165 不看题解,使劲找规律,应该是可以找到的,就是费时间! Problem Description As is ...

  6. HDU - 1284 钱币兑换问题 (找规律/完全背包)

    Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Out ...

  7. hdu 7092 仓颉造数 (猜测,手模数据找规律,推公式)

    hdu 7092 仓颉造数 分析: 先考虑一个问题,若平均数能转换成 111 ,那么调和平均数也能转换成 111 ,反之亦然 所以,问题就转换成了,生成平均数,判断平均数是否会出现 111 ,至于能能 ...

  8. hdu 4279 Number (找规律)

    http://acm.hdu.edu.cn/showproblem.php?pid=4279 题意: 给出a,b两个数,1<=a<=b 如果a,b不互质,且a%b != 0则说明a是b的特 ...

  9. HDU 6304 Chiaki Sequence Revisited(二分+找规律)

    题目链接 Chiaki Sequence Revisited Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

最新文章

  1. 看动画轻松理解「链表」实现「LRU缓存淘汰算法」
  2. Android文件的下载
  3. RISC-V生态未来的三种可能~
  4. php中隐藏和展开文章,手机端第一屏页面文章的展开和隐藏_html/css_WEB-ITnose
  5. mfc 窗体不可点击的原因_如何设计一个简单的Access登录窗体(2)
  6. iphone储存空间系统怎么清理_教你快速清理 iPhone 系统缓存垃圾,拒绝卡顿!
  7. 【日本語勉強】日本語四級文法突撃(11~20)
  8. 使用计算机系统管理商品存货,ERP管理系统中编码的意义
  9. window.createPopup()用法以及短消息提示框代码
  10. WCF NetTcpBinding Transport安全模式(7) ClientCredentialType证书验证模式---- ChainTrust验证模式...
  11. Centos 7.x 安装配置tomcat-8过程梳理
  12. 巨人肩膀_如何站在巨人的肩膀上
  13. 推荐 5 个优秀的 Javascript 图标库
  14. 怎样卸载deepin系统_win10系统双系统下卸载deepin的详细技巧
  15. (C#)Winform修改DateTimePicker控件的背景色Winform中日期控件DateTimePicker默认是不能修改背景色和边框色的
  16. 【数据中心机房是干什么的由哪些方面组成】
  17. 计算机毕业设计Java金融业撮合交易系统(源码+系统+mysql数据库+lw文档)
  18. 分享关于UE4中matinee工具的使用教程
  19. oracle 手机壁纸,Android修改手机壁纸功能
  20. 医学3d图像区域增长(以肺结节为例)

热门文章

  1. 碰到边缘就反弹的金币收集游戏,译者:lixingqiu
  2. 微信小程序运营系列(九)——一个传统行业“大老粗”怎么玩微信群
  3. 化学制药行业数字化供应链管理平台:精准数据采集,助力产业数字化升级
  4. Python 虎牙学习之舞蹈(一)
  5. mysql数据库索引和锁和日志
  6. ubuntu nomodeset设定
  7. tauri简单教程——以Flash应用为例
  8. 微信小程序搜索框的代码写法
  9. CSS让2个DIV在同一行显示的解决方法
  10. 总结下利用Python赚钱的方法,过年在家太闲,小赚看一笔,1000-5000不等