#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int W = 55;
const int Q = 3457;
const int R = (1<<16)%Q;
int qmi(int a, int k) {
int ans = 1;
while (k) {
if (k & 1)ans = (ans * a) % Q;
a = a * a % Q;
k >>= 1;
}
return (long long)ans% Q;
}
vector<vector<int>> genTree() {
queue<int> q;
vector<int> tmp;
vector<vector<int>> ans;
ans.push_back({ 64 });
q.push(32);
q.push(160);
q.push(-1);
while (q.size()) {
auto t = q.front();
q.pop();
if (t == -1) {
ans.push_back(tmp);
tmp.clear();
if(q.size()>1)
q.push(-1);
continue;
}
else {
tmp.push_back(t);
if ((t & 1) == 0) {
q.push(t / 2);
q.push((t + 192) / 2);
}
}
}
return ans;
}
vector<vector<int>> nttForward(vector<vector<int>> &tree) {
vector<vector<int>> ans;
for (auto& i : tree) {
vector<int> v;
for (auto j : i) {
v.push_back(qmi(W, j) * R % Q);
}
ans.push_back(v);
}
return ans;
}
vector<vector<int>> nttBackward(vector<vector<int>>& tree) {
vector<vector<int>> ans;
for (auto& i : tree) {
vector<int> v;
for (auto j : i) {
v.push_back(qmi(W, 384 - j) * R % Q);
}
ans.push_back(v);
}
return ans;
}
int getInv(int val) {
for (int i = 1; i < 3457; i++) {
if (qmi(val, i) == 1) {
return qmi(val, i - 1);
}
}
return -1;
}
int calcLastNttBackward() {
//b[j]-b[j+128]=2*t-a[j+128]
// =2*(a[j+128]*(55**64))-a[j+128]
// =a[j+128]*((2*(55**64)-1)
//
int t = (2 * qmi(55, 64) - 1) % Q;
int inv = getInv(t);
return inv * (1 << 16) % Q;
}
int main() {
auto tree = genTree();
auto ans=nttForward(tree);
auto b = nttBackward(tree);
for (auto& t : tree) {
for (auto i : t)cout << i << ' ';
cout << endl;
}
}
ntt768系数生成代码
最新推荐文章于 2024-07-22 09:38:37 发布