HDU 5666 Segment 数论+大数
2016-04-17 22:55
519 查看
题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5666bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=688&pid=1002
题解:
首先可以统计出三角形内所有的点数,(q-2)+(q-3)+...+1=(q-1)*(q-2)/2其次只要减去被线段割到的点,对于线段xi+yi=q,割到的点有gcd(xi,yi)-1=gcd(xi,q-xi)-1=gcd(xi,q)-1;由于q为质数,所以没有没被割到的点。
综上所述,答案为(q-1)*(q-2)/2;
由于(q-1)*(q-2)超过long long 的范围,所以不能直接求解。
以下提供两种解题方案。
1、用java求大数:
import java.util.*; import java.math.*; public class Main { public static void main(String args[]){ Scanner cin = new Scanner(System.in); long q,P; int tc=cin.nextInt(); while((tc--)>0){ q=cin.nextLong(); P=cin.nextLong(); BigInteger q1=new BigInteger(Long.toString(q-1)); BigInteger q2=new BigInteger(Long.toString(q-2)); BigInteger ans=q1.multiply(q2); ans=ans.divide(BigInteger.valueOf(2)); ans=ans.remainder(new BigInteger(Long.toString(P))); System.out.println(ans.toString()); } } }
2、模拟笔算二进制乘法
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using namespace std; const int maxn=1e5+10; typedef long long LL; const LL ONE=1; LL mul(LL a,LL b,LL p){ LL ret=0; for(;b>0;b>>=1){ if(b&1){ ret+=a; ret%=p; } a=(a+a)%p; } return ret; } int main() { int tc; scanf("%d",&tc); while(tc--) { LL q,p; scanf("%lld%lld",&q,&p); LL q1=q-1,q2=q-2; if(q1&1) q2/=2; else q1/=2; LL ans=mul(q1,q2,p); printf("%lld\n",ans); } return 0; }
相关文章推荐
- Processing 电子罗盘校准(以 MPU9250为例)
- CentOs7
- win 8.1 安装framework3.5
- 红黑树
- 虚函数表
- VS学习笔记之for的穷举
- 20145109 《Java程序设计》第七周学习总结
- 第五次作业
- java第七周学习总结
- Android 瀑布流控件的实现
- vsan和vvol概念理解
- 自考那些事儿(八):计算机网络原理(原理篇)之网络各层
- 前端构建工具gulpjs的使用介绍及技巧(转载)
- GET,POST——简述
- 稀疏矩阵的压缩存储及转置算法
- 李文哲博士-贝叶斯思想以及与最大似然估计、最大后验估计的区别
- PLMN
- Messenger
- ASP.NET Core的配置(1):读取配置信息
- 移动web HTML5使用photoswipe模仿微信朋友圈图片放大浏览