HDU 5666 Segment 数论+大数
题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5666
bc(中文):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求大数:
1 import java.util.*; 2 import java.math.*; 3 public class Main { 4 public static void main(String args[]){ 5 Scanner cin = new Scanner(System.in); 6 long q,P; 7 int tc=cin.nextInt(); 8 9 while((tc--)>0){ 10 q=cin.nextLong(); 11 P=cin.nextLong(); 12 BigInteger q1=new BigInteger(Long.toString(q-1)); 13 BigInteger q2=new BigInteger(Long.toString(q-2)); 14 BigInteger ans=q1.multiply(q2); 15 ans=ans.divide(BigInteger.valueOf(2)); 16 ans=ans.remainder(new BigInteger(Long.toString(P))); 17 System.out.println(ans.toString()); 18 } 19 } 20 }
2、模拟笔算二进制乘法
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 using namespace std; 6 7 const int maxn=1e5+10; 8 typedef long long LL; 9 10 const LL ONE=1; 11 LL mul(LL a,LL b,LL p){ 12 LL ret=0; 13 for(;b>0;b>>=1){ 14 if(b&1){ 15 ret+=a; 16 ret%=p; 17 } 18 a=(a+a)%p; 19 } 20 return ret; 21 } 22 23 int main() { 24 int tc; 25 scanf("%d",&tc); 26 while(tc--) { 27 LL q,p; 28 scanf("%lld%lld",&q,&p); 29 LL q1=q-1,q2=q-2; 30 if(q1&1) q2/=2; 31 else q1/=2; 32 LL ans=mul(q1,q2,p); 33 printf("%lld\n",ans); 34 } 35 return 0; 36 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?