C ++竞争性编程:在模N下简化表达式

时间:2017-06-13 12:34:59

标签: c++ operator-overloading operators modulo

codechef上存在许多问题,需要以某些数字为模运算 like in this one。我碰巧为每个用于例如

的算术运算符写% MOD

ans += (((sumX*sumZ) % MOD + (sumX + sumZ) % MOD) % MOD * Y) % MOD;

现在有没有办法用c ++隐式地做到这一点?

虽然this answer表示我们不能为内置类型重载算术运算符,但仍然是他们可以编写的任何方法 就像ans += (sumX*sumZ + (sumX + sumZ)) * Y  ?

2 个答案:

答案 0 :(得分:3)

您可以创建一个小包装,表示以数量为模的数字。

template<typename Number, Number Width>
class ModuloArithmetic
{
  Number n;
public:
  ModuloArithmetic(Number n) : n(n % Width) {}
  Number get() const { return n; }

  ModuloArithmetic& operator+= (ModuloArithmetic other)
  { n = (n + other.get()) % Width; return *this; }

  // Other modifying operators 
};

template<typename Number, Number Width>
ModuloArithmetic<Number, Width> operator+(
  ModuloArithmetic<Number, Width> lhs,
  ModuloArithmetic<Number, Width> rhs) {
  return lhs.get() + rhs.get();
}

// And so forth for the other arithmetic operations.

运算符总是处理包装类本身。因此,即使操作员没有明确地执行模运算,也会在返回时完成#34;拳击&#34;结果。

然后就一个简单的问题来定义你的所有数字:

using num_t = ModuloArithmetic<int, MOD>;
num_t sumX, sumZ;

答案 1 :(得分:0)

Thanks to @StoryTeller and @MSalters, I finally made this snippet that I can use for solving coding problems-

#define ll long long int
#define MOD 1000000007

template<typename Number, Number m>
class modNum
{
private:
    Number a;
public:
    // overloading '<<'
    friend ostream& operator<<(ostream& os, modNum const & num) {
          return os << num.a;
      }
    modNum(Number a) : a(a % m) {}

    Number get() const { return a; }

    modNum operator+= (modNum b){ a = (a + b.get()) % m; return a; }
    modNum operator*= (modNum b){ a = (a * b.get()) % m; return a; }
    modNum operator/= (modNum b){ a = (a / b.get()) % m; return a; }
    modNum operator-= (modNum b){ a = (a - b.get()) % m; return a; }
    modNum operator + (modNum b){modNum t = (a + b.get()) % m; return t;}
    modNum operator * (modNum b){modNum t = (a * b.get()) % m; return t;}
    modNum operator / (modNum b){modNum t = (a / b.get()) % m; return t;}
    modNum operator - (modNum b){modNum t = (a - b.get()) % m; return t;}

};
typedef modNum<ll, MOD> num_t;
//testing the code-
int int_max = 2147483647;
int sqroot_max = sqrt(int_max);

int main()
{
    num_t sumX(sqroot_max),sumZ(sqroot_max),Y(sqroot_max);
    cout<<(sumX*sumZ + sumX+sumZ)*Y;
    // (((sumX*sumZ) % MOD + (sumX + sumZ) % MOD) % MOD * Y) % MOD;
    return 0;
}