/**
- struct Point {
- int x;
- int y;
- };
- */
class Solution
{
uint64_t Modp = 1000000007;
uint32_t Inv(uint64_t num)
{
uint32_t result = 1, Power = 1000000005;
while (Power > 0)
{
if (Power & 1)
result = result * num % Modp;
Power >>= 1;
num = num * num % Modp;
}
return result;
}
Point TwoTimesPoint(Point P)
{
Point R;
uint64_t k = (3 * (uint64_t)P.x * P.x + 1) % Modp * Inv(2 * P.y % Modp) % Modp;
R.x = (k * k + 2 * Modp - 2 * P.x) % Modp;
R.y = (k * (P.x + Modp - R.x) + Modp - P.y) % Modp;
return R;
}
Point TwoPointsAdd(Point P, Point Q)
{
Point R;
uint64_t k = (Q.y + Modp - P.y) * Inv((Q.x + Modp - P.x) % Modp) % Modp;
R.x = (k * k % Modp + 2 * Modp - P.x - Q.x) % Modp;
R.y = (k * (P.x + Modp - R.x) + Modp - P.y) % Modp;
return R;
}
public:
/**
- @param P Point类
- @param n int整型
- @return Point类
- /
Point NTimesPoint(Point P, int n)
{// write code here Point PointTimes[30] = {P}, NP; uint8_t NBin[30], Leath = 0, Flag = 0; for (; n > 0; Leath += 1) { NBin[Leath] = n & 1; n >>= 1; } for (uint8_t i = 1; i < Leath; i += 1) PointTimes[i] = TwoTimesPoint(PointTimes[i - 1]); while (!NBin[Flag++]) ; NP = PointTimes[Flag - 1]; for (uint8_t i = Flag; i < Leath; i++) { if (NBin[i]) NP = TwoPointsAdd(NP, PointTimes[i]); } return NP;
}
};