Q. HugeInteger 大整数运算 (FFT)

传统 1000 ms 256 MiB
标准 IO
文本比较

题目描述

题目描述

请创建一个名为 HugeInteger 的类,用于处理超大整数的存储与运算。

你需要实现以下功能:

  1. 数值存储:能够处理长度达到 3×1053 \times 10^5 位的非负整数。
  2. 运算支持
    • ADD:加法。
    • SUB:减法(保证被减数大于等于减数)。
    • MUL:乘法(本题核心难点,需高效实现)。
  3. 比较支持
    • EQUAL:判断是否相等。
    • GREATER:判断是否大于。
    • LESS:判断是否小于。

输入说明: 每组数据包含一个操作指令字符串,以及两个大整数 AABB。你需要根据指令计算结果或输出布尔判断。

为了方便后续的作业,本次题目要求对类进行运算符重载封装,下面给出一个参考(你也可以自行设计类接口)。

class HugeInt
{
   friend ostream &operator<<( ostream &, const HugeInt & );
public:
   HugeInt( long = 0 ); // 转换/默认构造函数
   HugeInt( const char * ); // 转换构造函数
   
   // HugeInt + HugeInt
   HugeInt operator+( const HugeInt & ) const;
   // HugeInt + int
   HugeInt operator+( int ) const;
   // HugeInt + 表示大整数的字符串
   HugeInt operator+( const char * ) const;
   
   bool operator==( const HugeInt & ) const; // 相等运算符
   bool operator!=( const HugeInt & ) const; // 不等运算符
   bool operator<( const HugeInt & ) const;  // 小于运算符
   bool operator<=( const HugeInt & ) const; // 小于等于运算符
   bool operator>( const HugeInt & ) const;  // 大于运算符
   bool operator>=( const HugeInt & ) const; // 大于等于运算符
   
   HugeInt operator-( const HugeInt & ) const; // 减法运算符
   HugeInt operator*( const HugeInt & ) const; // 乘法运算符
   HugeInt operator/( const HugeInt & ) const; // 除法运算符(本题不要求实现,保留接口)
   
   int getLength() const; // 返回数字长度

private:

}; // end class HugeInt

提示

如果使用上一次的压位乘法,在本题的数据范围下,仍然需要 9×1089\times 10^8 次运算,这无法在合理时间内完成。你需要使用基于快速傅里叶变换(FFT)的乘法算法,将时间复杂度降低到 O(NlogN)O(N \log N) 级别,从而高效完成大整数乘法运算。

输入格式

第一行包含一个整数 1T101 \le T \le 10,表示测试数据的组数。 接下来 TT 行,每行格式如下: OperationABOperation \quad A \quad B 其中 OperationOperation 为字符串指令,取值为 ADD, SUB, MUL, EQUAL, GREATER, LESS 之一。 AABB 为两个非负大整数的字符串形式。

输出格式

对于每组数据,输出一行:

  • 若是运算指令(ADD, SUB, MUL),输出计算结果的十进制字符串。
  • 若是比较指令(EQUAL, GREATER, LESS),若条件成立输出 True,否则输出 False

样例

样例输入

4
ADD 123456789 987654321
SUB 1000 1
MUL 99999 99999
GREATER 500 100

样例输出

1111111110
999
9999800001
True

数据范围与提示

数据范围与提示

  • 数据共分为两档:
    • Small (30%):数字长度 L1000L \le 1000。普通的一位一存模拟即可通过。
    • Large (70%):数字长度 L300000L \le 300000

思考

  1. 为什么不用快速数论变换(NTT)操作点值和系数多项式?