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 }

 

转载于:https://www.cnblogs.com/fenice/p/5402696.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值