当前位置:网站首页>NTT template for Tourism
NTT template for Tourism
2022-07-08 00:46:00 【Foolish last words】
template <typename T>
class Modular {
public:
using Type = typename decay<decltype(T::value)>::type;
constexpr Modular() : value() {}
template <typename U>
Modular(const U& x) {
value = normalize(x);
}
template <typename U>
static Type normalize(const U& x) {
Type v;
if (-mod() <= x && x < mod()) v = static_cast<Type>(x);
else v = static_cast<Type>(x % mod());
if (v < 0) v += mod();
return v;
}
const Type& operator()() const { return value; }
template <typename U>
explicit operator U() const { return static_cast<U>(value); }
constexpr static Type mod() { return T::value; }
Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; }
Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; }
template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); }
template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); }
Modular& operator++() { return *this += 1; }
Modular& operator--() { return *this -= 1; }
Modular operator++(int) { Modular result(*this); *this += 1; return result; }
Modular operator--(int) { Modular result(*this); *this -= 1; return result; }
Modular operator-() const { return Modular(-value); }
template <typename U = T>
typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) {
#ifdef _WIN32
uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
asm(
"divl %4; \n\t"
: "=a" (d), "=d" (m)
: "d" (xh), "a" (xl), "r" (mod())
);
value = m;
#else
value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
#endif
return *this;
}
template <typename U = T>
typename enable_if<is_same<typename Modular<U>::Type, long long>::value, Modular>::type& operator*=(const Modular& rhs) {
long long q = static_cast<long long>(static_cast<long double>(value) * rhs.value / mod());
value = normalize(value * rhs.value - q * mod());
return *this;
}
template <typename U = T>
typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) {
value = normalize(value * rhs.value);
return *this;
}
Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); }
friend const Type& abs(const Modular& x) { return x.value; }
template <typename U>
friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);
template <typename U>
friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);
template <typename V, typename U>
friend V& operator>>(V& stream, Modular<U>& number);
private:
Type value;
};
template <typename T>
class NTT {
public:
using Type = typename decay<decltype(T::value)>::type;
static Type md;
static Modular<T> root;
static int base;
static int max_base;
static vector<Modular<T>> roots;
static vector<int> rev;
static void clear() {
root = 0;
base = 0;
max_base = 0;
roots.clear();
rev.clear();
}
static void init() {
md = T::value;
assert(md >= 3 && md % 2 == 1);
auto tmp = md - 1;
max_base = 0;
while (tmp % 2 == 0) {
tmp /= 2;
max_base++;
}
root = 2;
while (power(root, (md - 1) >> 1) == 1) {
root++;
}
assert(power(root, md - 1) == 1);
root = power(root, (md - 1) >> max_base);
base = 1;
rev = {0, 1};
roots = {0, 1};
}
static void ensure_base(int nbase) {
if (md != T::value) {
clear();
}
if (roots.empty()) {
init();
}
if (nbase <= base) {
return;
}
assert(nbase <= max_base);
rev.resize(1 << nbase);
for (int i = 0; i < (1 << nbase); i++) {
rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
}
roots.resize(1 << nbase);
while (base < nbase) {
Modular<T> z = power(root, 1 << (max_base - 1 - base));
for (int i = 1 << (base - 1); i < (1 << base); i++) {
roots[i << 1] = roots[i];
roots[(i << 1) + 1] = roots[i] * z;
}
base++;
}
}
static void fft(vector<Modular<T>> &a) {
int n = (int) a.size();
assert((n & (n - 1)) == 0);
int zeros = __builtin_ctz(n);
ensure_base(zeros);
int shift = base - zeros;
for (int i = 0; i < n; i++) {
if (i < (rev[i] >> shift)) {
swap(a[i], a[rev[i] >> shift]);
}
}
for (int k = 1; k < n; k <<= 1) {
for (int i = 0; i < n; i += 2 * k) {
for (int j = 0; j < k; j++) {
Modular<T> x = a[i + j];
Modular<T> y = a[i + j + k] * roots[j + k];
a[i + j] = x + y;
a[i + j + k] = x - y;
}
}
}
}
static vector<Modular<T>> multiply(vector<Modular<T>> a, vector<Modular<T>> b) {
if (a.empty() || b.empty()) {
return {};
}
int eq = (a == b);
int need = (int) a.size() + (int) b.size() - 1;
int nbase = 0;
while ((1 << nbase) < need) nbase++;
ensure_base(nbase);
int sz = 1 << nbase;
a.resize(sz);
b.resize(sz);
fft(a);
if (eq) b = a; else fft(b);
Modular<T> inv_sz = 1 / static_cast<Modular<T>>(sz);
for (int i = 0; i < sz; i++) {
a[i] *= b[i] * inv_sz;
}
reverse(a.begin() + 1, a.end());
fft(a);
a.resize(need);
return a;
}
};
边栏推荐
- DNS series (I): why does the updated DNS record not take effect?
- Stock account opening is free of charge. Is it safe to open an account on your mobile phone
- Codeforces Round #804 (Div. 2)(A~D)
- SDNU_ACM_ICPC_2022_Summer_Practice(1~2)
- Application practice | the efficiency of the data warehouse system has been comprehensively improved! Data warehouse construction based on Apache Doris in Tongcheng digital Department
- v-for遍历元素样式失效
- “一个优秀程序员可抵五个普通程序员”,差距就在这7个关键点
- Huawei switch s5735s-l24t4s-qa2 cannot be remotely accessed by telnet
- 服务器防御DDOS的方法,杭州高防IP段103.219.39.x
- Which securities company has a low, safe and reliable account opening commission
猜你喜欢
快速上手使用本地测试工具postman
语义分割模型库segmentation_models_pytorch的详细使用介绍
深潜Kotlin协程(二十二):Flow的处理
5g NR system messages
ReentrantLock 公平锁源码 第0篇
Qt添加资源文件,为QAction添加图标,建立信号槽函数并实现
【愚公系列】2022年7月 Go教学课程 006-自动推导类型和输入输出
Reentrantlock fair lock source code Chapter 0
Service mesh introduction, istio overview
3年经验,面试测试岗20K都拿不到了吗?这么坑?
随机推荐
基于微信小程序开发的我最在行的小游戏
Emotional post station 010: things that contemporary college students should understand
深潜Kotlin协程(二十三 完结篇):SharedFlow 和 StateFlow
LeetCode刷题
Operating system principle --- summary of interview knowledge points
After going to ByteDance, I learned that there are so many test engineers with an annual salary of 40W?
服务器防御DDOS的方法,杭州高防IP段103.219.39.x
Vscode software
Introduction to paddle - using lenet to realize image classification method I in MNIST
[Yugong series] go teaching course 006 in July 2022 - automatic derivation of types and input and output
【转载】解决conda安装pytorch过慢的问题
Cancel the down arrow of the default style of select and set the default word of select
Service Mesh的基本模式
基于人脸识别实现课堂抬头率检测
Cascade-LSTM: A Tree-Structured Neural Classifier for Detecting Misinformation Cascades(KDD20)
他们齐聚 2022 ECUG Con,只为「中国技术力量」
Jouer sonar
C# 泛型及性能比较
paddle入门-使用LeNet在MNIST实现图像分类方法一
Service mesh introduction, istio overview