在一些 K 个不同的整数、模786433处找到多项式的值
Find the value of polynomial at some K different integers, modulo 786433
给你一个带有整数系数的 N 次多项式。你的任务是在某些 K 个不同的整数、模786433找到这个多项式的值。
输入
输入的第一行包含一个整数 N,表示多项式的次数。
每个测试用例的以下行包含 (N+1) 个整数,表示多项式的系数。此行中的第 i 个数字表示多项式 a_0 + a_1 × x_1 + a_2 × x_2 + ... + a_N × x_N 中的系数 a_(i-1)。
以下行包含一个整数 Q,表示查询数。
以下 Q 行的第 j 个包含表示查询的整数x_j。
输出
对于每个查询,输出一行包含相应查询的答案。换句话说,输出的第 j 行应该有一个等于 a_0 + a_1 × x_j + a_2 × x_j^2 + ... + a_N × x_j^N 模786433的整数。
约束和子任务
- 0 ≤ a_i, x_j <786433
- 子任务 #1(37 分):0 ≤ N、Q ≤ 1000
- 子任务 #2(63 分): 0 ≤ N, Q ≤ 2.5 × 10^5
例
输入:21 2 33789
输出:36便士209262
解释
示例案例 1。
- 查询 1:1 + 2 × 7 + 3 × 7 × 7 = 162
- 查询 2:1 + 2 × 8 + 3 × 8 × 8 = 209
- 查询 3:1 + 2 × 9 + 3 × 9 × 9 = 262
下面是在 O(n log n) 时间内运行的代码。我使用快速傅里叶变换将两个多项式相乘。
为什么我需要对所有计算使用模786433运算符?我知道这可能与 int 溢出有关?这在竞争性编程问题中很正常吗?
#include <cstdio>
#include <algorithm>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
#define all(a) (a).begin(),(a).end()
#define pb push_back
#define sz(a) ((int)(a).size())
#define mp make_pair
#define fi first
#define se second
typedef pair<int, int> pint;
typedef long long ll;
typedef vector<int> vi;
#define MOD 786433
#define MAGIC (3*(1<<18))
const int root = 10;
void fft(vi &a, int wn = root)
{
int n = sz(a);
if (n == 3)
{
int a1 = a[0] + a[1] + a[2];
int a2 = (a[0] + a[1] * 1LL * root + a[2] * (root * 1LL * root)) % MOD;
a[1] = a1;
a[2] = a2;
return;
}
vi a0(n / 2), a1(n / 2);
for (int i = 0, j = 0; i<n; i += 2, ++j)
{
a0[j] = a[i];
a1[j] = a[i + 1];
}
int wnp = (wn * 1LL * wn) % MOD;
fft(a0, wnp);
fft(a1, wnp);
int w = 1;
for (int i = 0; i<n / 2; ++i) {
int twiddle = (w * 1LL * a1[i]) % MOD;
a[i] = (a0[i] + twiddle) % MOD;
a[i + n / 2] = (a0[i] - twiddle + MOD) % MOD;
w = (w * 1LL * wn) % MOD;
}
}
int n;
vi coef;
void poly(stringstream& ss)
{
ss >> n;
n++;
for (int i = 0; i<n; i++)
{
int x;
ss >> x;
coef.pb(x);
}
while (sz(coef)<MAGIC)
coef.pb(0);
vi ntt = coef;
fft(ntt);
vector<pint> sm;
sm.pb(mp(0, coef[0]));
int pr = 1;
for (int i = 0; i<sz(ntt); i++)
{
sm.pb(mp(pr, ntt[i]));
pr = (pr * 1LL * root) % MOD;
}
sort(all(sm));
int q;
ss >> q;
while (q--)
{
int x;
ss >> x;
int lo = 0, hi = sz(sm) - 1;
while (lo<hi)
{
int m = (lo + hi) / 2;
if (sm[m].fi<x)
lo = m + 1;
else
hi = m;
}
printf("%dn", sm[lo].se);
}
}
void test1()
{
stringstream ss;
{
int degree = 2;
ss << degree << "n";
string coefficients{ "1 2 3" };
ss << coefficients << "n";
int NoQueries = 3;
ss << NoQueries << "n";
int query = 7;
ss << query << "n";
query = 8;
ss << query << "n";
query = 9;
ss << query << "n";
}
poly(ss);
}
int main()
{
test1();
return 0;
}
顺便说一句:这个问题来自 2016 年 7 月的挑战 @ 代码厨师
re
" 为什么我需要在所有计算中使用模786433运算符?我知道这可能与 int 溢出有关?这在竞争性编程问题中很正常吗?
是的,这是为了避免溢出。
是的,这在编程问题集和竞赛中是正常的。
相关文章:
- 将依赖名称显式标记为类型名和模板的奇怪之处
- c++模板来表示多项式
- 为什么g++在未执行的代码处标记强制转换错误
- 在 C++ 中访问数组负索引处的内存不会返回垃圾
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 在多个时间戳处执行函数
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- 映射如何在给定键处搜索值
- 在 ******.exe 中0x00000000772CA267 (ntdll.dll) 处未处理的异常:0xC0000
- "错误 C0000:语法错误,令牌"<EOF>"处出现意外$end,并且不确定
- 为什么 operator() 处的指针成员不起作用?
- 使用链表数据结构打印多项式
- 警告级别为 3 的 int 的 std::vector push_back 处的编译器警告
- 以下示例中给出的构造有什么不幸之处?
- 需要帮助重载多项式类运算符C++
- 在类内和类外的定义处执行类转发声明是否有区别
- 矢量指针索引处的读取元素
- 如何修复此教科书程序以在C++中添加多项式?
- 如何对两个 4 位数字进行乘法,将它们视为 C++ 中的多项式
- 在一些 K 个不同的整数、模786433处找到多项式的值