题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5666
题目大意:给定 T T 组数据,每组数据给定和 P P ,问直线在第一象限形成的三角形内部有多少个整数点,结果对 P P 取模;
数据范围: , 1≤q≤1018 1 ≤ q ≤ 10 18 , 1≤P≤1018 1 ≤ P ≤ 10 18
题目解答:俄罗斯乘法(复杂度:
O(log2q)
O
(
log
2
q
)
) / Java大数取模(复杂度:
O(1)
O
(
1
)
) / 大数乘法取模转换为作差求余数(复杂度:
O(1)
O
(
1
)
)
原题实际上为求
∑i=1q−2imodP=(q−2)∗(q−1)/2modP
∑
i
=
1
q
−
2
i
mod
P
=
(
q
−
2
)
∗
(
q
−
1
)
/
2
mod
P
,由于
q
q
的范围很大,直接乘爆long long,采用俄罗斯乘法,或者用Java大数
另外一种思路,由于 ,
⌊⌋
⌊
⌋
表示向下取整,可以把大数乘法取模转换为作差求余数
题目代码:
1.俄罗斯乘法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <bitset>
using namespace std;
//俄罗斯乘法(快速积)
long long mul(long long a, long long b, long long p)
{
long long ans = 0;
for(; b; b >>= 1)
{
if(b & 1) ans = (ans + a) % p;
a = a * 2 % p;
}
return ans;
}
int main()
{
int t;
cin >> t;
while(t--)
{
long long q, p, ans;
cin >> q >> p;
if(q % 2)
ans = mul((q-1)/2, q-2, p) % p;
else
ans = mul(q-1, (q-2)/2, p) % p;
cout << ans << endl;
}
}
2.Java大数
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
int x;
x=cin.nextInt();
while(x!=0)
{
x--;
BigInteger c=new BigInteger("2");
BigInteger e=new BigInteger("1");
BigInteger a=cin.nextBigInteger();
BigInteger d=a.subtract(c);
BigInteger f=a.subtract(e);
BigInteger b=cin.nextBigInteger();
BigInteger ans=f.multiply(d);
ans=ans.divide(c);
System.out.println(ans.remainder(b));
}
}
}
3.大数乘法取模转换
#include <cstdio>
#include <cstring>
#include <iostream>
#include <bitset>
using namespace std;
long long mul(long long a, long long b, long long p)
{
a %= p, b %= p;
long long c = (long double)a * b / p;
long long ans = a * b - c * p;
if(ans < 0) ans += p;
else if (ans >= p) ans -= p;
return ans;
}
int main()
{
int t;
cin >> t;
while(t--)
{
long long q, p, ans;
cin >> q >> p;
if(q % 2)
ans = mul((q-1)/2, q-2, p) % p;
else
ans = mul(q-1, (q-2)/2, p) % p;
cout << ans << endl;
}
}

本博客详细介绍了如何解决HDU5666问题,主要涉及俄罗斯乘法算法,Java大数取模以及大数乘法取模的转换技巧。针对给定的直线在第一象限内形成的三角形整数点数量,通过优化算法在大数运算下进行高效取模计算,包括O(log2q)复杂度的俄罗斯乘法和O(1)复杂度的Java大数及作差求余数方法。

2502

被折叠的 条评论
为什么被折叠?



