文章目录
直接上代码
// #define int long long
#ifndef MOD
#define MOD 1e9+7
class Num {
private:
static const int mod = MOD;
int val = 0;
protected:
static inline int norm(int x) {
if (x < 0) {
int cnt = abs(x)/mod + 1;
x += mod*cnt;
}
return x%mod;
}
static int binPow(int base, int expo, int p) {
if (expo == 0) { // 防止 mod 1
return 1 % p;
}
base %= p;
int half = binPow(base, expo>>1, p);
if (expo & 1) {
return half*half%p * base%p;
} else {
return half*half%p;
}
}
public:
Num() {}
Num(int val):val(norm(val)) {}
Num(const Num& num) {
this->val = num.val;
}
~Num() {}
int getVal() {
return this->val;
}
void setVal(const int val) {
this->val = norm(val);
}
int& operator()() {
return this->val;
}
public:
friend std::istream& operator>>(std::istream& cin, Num& num) {
cin >> num.val;
num.val = num.norm(num.val);
return cin;
}
friend std::ostream& operator<<(std::ostream& cout, Num& num) {
cout << num.val;
return cout;
}
friend std::ostream& operator<<(std::ostream& cout, Num&& num) {
cout << num.val;
return cout;
}
public:
Num& operator+=(const Num& rhs) {
val = norm(val + rhs.val);
return *this;
}
Num& operator-=(const Num& rhs) {
val = norm(val - rhs.val);
return *this;
}
Num& operator*=(const Num& rhs) {
val = norm(val * rhs.val);
return *this;
}
Num& operator/=(const Num& rhs) {
int inverseElement = binPow(rhs.val, mod-2, mod);
val = norm(val * inverseElement);
return *this;
}
public:
Num operator+() {
Num tmp = val;
return tmp;
}
Num operator-() {
Num tmp = -val;
return tmp;
}
friend Num operator+(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp += rhs;
return tmp;
}
friend Num operator-(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp -= rhs;
return tmp;
}
friend Num operator*(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp *= rhs;
return tmp;
}
friend Num operator/(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp /= rhs;
return tmp;
}
public:
Num operator++(signed) { // 后置
Num tmp = *this;
val = norm(val+1);
return tmp;
}
Num operator--(signed) { // 后置
Num tmp = *this;
val = norm(val-1);
return tmp;
}
Num& operator++() { // 前置
val = norm(val+1);
return *this;
}
Num& operator--() { // 前置
val = norm(val-1);
return *this;
}
public:
bool operator!() const {
return val == 0;
}
bool operator==(const Num& rhs) const {
return val == rhs.val;
}
bool operator!=(const Num& rhs) const {
return val != rhs.val;
}
bool operator>(const Num& rhs) const {
return val > rhs.val;
}
bool operator>=(const Num& rhs) const {
return val >= rhs.val;
}
bool operator<(const Num& rhs) const {
return val < rhs.val;
}
bool operator<=(const Num& rhs) const {
return val <= rhs.val;
}
bool operator&&(const Num& rhs) const {
return val && rhs.val;
}
bool operator||(const Num& rhs) const {
return val || rhs.val;
}
};
#endif // MOD
前言
在一些题目或情景中,需要我们对一个数进行取模运算,但是每次手动写取模会比较麻烦,因此就有了本文。
在C++,C#等语言中支持重载运算符,那么我们就可以自己写一个工具类,来满足自动取模的要求。
各部分介绍
宏定义
// #define int long long
#ifndef MOD
#define MOD 1e9+7
class Num {};
#endif // MOD
成员变量
private:
static const int mod = MOD;
int val = 0;
辅助函数
protected:
static inline int norm(int x) {
if (x < 0) {
int cnt = abs(x)/mod + 1;
x += mod*cnt;
}
return x%mod;
}
static int binPow(int base, int expo, int p) {
if (expo == 0) { // 防止 mod 1
return 1 % p;
}
base %= p;
int half = binPow(base, expo>>1, p);
if (expo & 1) {
return half*half%p * base%p;
} else {
return half*half%p;
}
}
构造和析构
public:
Num() {}
Num(int val):val(norm(val)) {}
Num(const Num& num) {
this->val = num.val;
}
~Num() {}
get/set
public:
int getVal() {
return this->val;
}
void setVal(const int val) {
this->val = norm(val);
}
仿函数
public:
int& operator()() {
return this->val;
}
标准输入输出
public:
friend std::istream& operator>>(std::istream& cin, Num& num) {
cin >> num.val;
num.val = num.norm(num.val);
return cin;
}
friend std::ostream& operator<<(std::ostream& cout, Num& num) {
cout << num.val;
return cout;
}
friend std::ostream& operator<<(std::ostream& cout, Num&& num) {
cout << num.val;
return cout;
}
重载+= -= *= /=
public:
Num& operator+=(const Num& rhs) {
val = norm(val + rhs.val);
return *this;
}
Num& operator-=(const Num& rhs) {
val = norm(val - rhs.val);
return *this;
}
Num& operator*=(const Num& rhs) {
val = norm(val * rhs.val);
return *this;
}
Num& operator/=(const Num& rhs) {
int inverseElement = binPow(rhs.val, mod-2, mod);
val = norm(val * inverseElement);
return *this;
}
重载+ - * /
public:
Num operator+() {
Num tmp = val;
return tmp;
}
Num operator-() {
Num tmp = -val;
return tmp;
}
friend Num operator+(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp += rhs;
return tmp;
}
friend Num operator-(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp -= rhs;
return tmp;
}
friend Num operator*(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp *= rhs;
return tmp;
}
friend Num operator/(const Num& lhs, const Num& rhs) {
Num tmp = lhs;
tmp /= rhs;
return tmp;
}
重载自增,自减运算符++ --
public:
Num operator++(signed) { // 后置
Num tmp = *this;
val = norm(val+1);
return tmp;
}
Num operator--(signed) { // 后置
Num tmp = *this;
val = norm(val-1);
return tmp;
}
Num& operator++() { // 前置
val = norm(val+1);
return *this;
}
Num& operator--() { // 前置
val = norm(val-1);
return *this;
}
重载比较、逻辑运算符
public:
bool operator!() const {
return val == 0;
}
bool operator==(const Num& rhs) const {
return val == rhs.val;
}
bool operator!=(const Num& rhs) const {
return val != rhs.val;
}
bool operator>(const Num& rhs) const {
return val > rhs.val;
}
bool operator>=(const Num& rhs) const {
return val >= rhs.val;
}
bool operator<(const Num& rhs) const {
return val < rhs.val;
}
bool operator<=(const Num& rhs) const {
return val <= rhs.val;
}
bool operator&&(const Num& rhs) const {
return val && rhs.val;
}
bool operator||(const Num& rhs) const {
return val || rhs.val;
}
一些使用注意点
signed main () {
Num num = 100;
// 普通数值在左边不行
// if (0 < num)
if (num > 0) {
vector<Num> arr(num()+1);
/**
num * 114514
这里实际上是进行了类型转化
先将114514转化成Num类型的数据,再计算(if 中的 num > 0 也是)
可以在构造和析构中输出检验
*/
iota(arr.begin(), arr.end(), num * 114514);
cout << arr[num.getVal()] << endl;
}
system("pause");
return 0;
}