7/16 训练笔记
闲话
插,就硬插,插完就过了(
P4781 【模板】拉格朗日插值
模板题,写拉格朗日插值即可。
代码:
#include <bits/stdc++.h>
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; i++)
using namespace std;
const int mod = 998244353;
int x[2010], y[2010], n, k;
int qpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) (res *= x) %= mod;
(x *= x) %= mod;
y >>= 1;
}
return res;
}
void lagrange() {
int ans = 0;
rep (i, 1, n) {
int res1 = 1, res2 = 1;
rep (j, 1, n) {
if (i == j) continue;
(res1 *= ((k - x[j]) % mod + mod) % mod) %= mod;
(res2 *= ((x[i] - x[j]) % mod + mod) % mod) %= mod;
}
(ans += (y[i] * res1 % mod) * qpow(res2, mod - 2) % mod) %= mod;
}
cout << (ans + mod) % mod << "\n";
}
signed main() {
cin >> n >> k;
rep (i, 1, n) {
cin >> x[i] >> y[i];
}
lagrange();
}
P4593 [TJOI2018] 教科书般的亵渎
注意到答案是一大堆形如 \(\Sigma_{i = 1}^n i^k\) 的项加起来,那么拉格朗日插值。
代码:
#include <bits/stdc++.h>
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; i++)
using namespace std;
const int mod = 1e9 + 7;
int x[2010], y[2010], a[60], t, n, m, k, cnt, ans;
int qpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) (res *= x) %= mod;
(x *= x) %= mod;
y >>= 1;
}
return res;
}
int lagrange() {
int ans = 0;
rep (i, 1, cnt + 2) {
int res1 = 1, res2 = 1;
rep (j, 1, cnt + 2) {
if (i == j) continue;
(res1 *= ((k - x[j]) % mod + mod) % mod) %= mod;
(res2 *= ((x[i] - x[j]) % mod + mod) % mod) %= mod;
}
(ans += (y[i] * res1 % mod) * qpow(res2, mod - 2) % mod) %= mod;
}
return (ans + mod) % mod;
}
signed main() {
cin >> t;
while (t--) {
cin >> n >> m;
rep (i, 1, m) {
cin >> a[i];
}
cnt = m + 1;
rep (i, 1, m + 3) {
x[i] = i;
y[i] = (y[i - 1] + qpow(i, cnt)) % mod;
}
sort(a + 1, a + m + 1);
ans = 0;
rep (i, 1, m + 1) {
int len = a[i - 1] + 1;
k = n - len + 1;
(ans += lagrange()) %= mod;
rep (j, i, m) ans = ((ans - qpow(a[j] - len + 1, cnt)) % mod + mod) % mod;
}
cout << ans << "\n";
}
}