/**

  • 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;
}
};