提示:本题难度NOI/NOI+/CTSC较难,最好先学会方法再写。
题目背景
为了题目要求,我们对积性函数进行重定义:不保证 f(1)=1f(1)=1。
题目描述
这是一道非传统题。
给定一个积性函数 f(d)f(d)。对于每一个测试点,我们会在附件中给出 g(n)=\sum_{d|n}f(d)g(n)=∑d∣nf(d) 的其中 kk 项 \bmod\ 998244353mod 998244353 的值,这部分也会在输入中出现。接着,对于每一个测试点,有 tt 组数据。对于每组数据,输入 dd,请输出 f(d)\bmod998244353f(d)mod998244353 的值。
输入格式
第一行为 kk,接下来每一行会有两个正整数,分别为 dd 与 g(d)g(d)。
之后输入两个数 t,idt,id,分别表示数据组数与数据点编号。对于每组数据,输入一个正整数 nn。
输出格式
对于每组数据,输出一个正整数表示答案。
输入输出样例
输入 #1复制
10 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 3 -1 1 2 3
输出 #1复制
1 1 2
说明/提示
【样例解释】
由于 g(d)=dg(d)=d,因此 f(d)=\varphi(d)f(d)=φ(d),结果正确。
【数据范围】
对于每个测试点:
如果你正确回答了 n\le kn≤k 的测试数据,你将得到 20\%20% 的分数。
如果你正确回答了所有测试数据,你将得到剩余 80\%80% 的分数。所以,如果你无法正确回答,也请随机输出一个数来保证格式正确。
【数据范围】
\text{Id}Id | \text{Name}Name | \text{Score}Score | n\leqn≤ | k=k= | t=t= |
---|---|---|---|---|---|
00 | \text{Epsilon}Epsilon | 55 | 10^6106 | 100100 | 1010 |
11 | \text{Division}Division | 55 | 10^9109 | 100100 | 1010 |
22 | \text{Unknown}Unknown | 55 | 10^{18}1018 | 11 | 1010 |
33 | \text{Random}Random | 1010 | 10^5105 | 10^5105 | 10^5105 |
44 | \text{Double}Double | 1010 | 10^9109 | 100100 | 1010 |
55 | \text{Hack}Hack | 1010 | 10^9109 | 3162331623 | 11 |
66 | \text{Square}Square | 1515 | 10^{18}1018 | 100100 | 55 |
77 | \text{Poly}Poly | 2020 | 10^9109 | 10^5105 | 100100 |
88 | \text{Thanks}Thanks | 2020 | 10^5105 | 44 | 10^5105 |
附件下载
sum.zip1.53MB
上代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;
const int MAXN = 1e6 + 10;
const int mod = 998244353;
int k; ll f[MAXN];
namespace Sub0 {
inline
ll solve(ll n) {
int res = 0;
for (ll i = 2; i <= n; i++) {
if (n % i) continue;
if (n / i % i) n /= i, res ^= 1;
else return 0;
}
if (n > 1) res ^= 1;
return res ? mod - 1 : 1;
}
}
namespace Sub1 {
inline
ll solve(ll n) {
return 1;
}
}
namespace Sub2 {
inline
ll solve(ll n) {
return 0;
}
}
namespace Sub3 {
bool d = 1;
inline
void init() {
for (int i = 1; i <= k; i++) {
for (int j = i << 1; j <= k; j += i) f[j] = (f[j] - f[i] + mod) % mod;
}
}
inline
ll solve(ll n) {
if (d) init(), d = 0;
return f[n];
}
}
namespace Sub4 {
inline
ll phi(int n) {
int res = n;
for (int i = 2; i <= n / i; i++) {
if (n % i == 0) for (res -= res / i; n % i == 0; n /= i);
}
if (n > 1) res -= res / n;
return (ll)res * res % mod;
}
inline
ll solve(ll n) {
ll ans = 0;
for (int i = 1; i <= n / i; i++) {
if (n % i) continue;
ans = (ans + phi(i)) % mod;
if (i != n / i) ans = (ans + phi(n / i)) % mod;
}
return ans;
}
}
namespace Sub5 {
inline
void init() {
for (int i = 1; i <= k; i++) {
for (int j = i << 1; j <= k; j += i) f[j] = (f[j] - f[i] + mod) % mod;
}
}
inline
ll solve(ll n) {
init();
for (int i = 2; i <= n / i; i++) {
if (n % i == 0) return f[i] * f[n / i] % mod;
}
}
}
namespace Sub6 {
const int prime[] = { 2, 3, 5, 7, 11, 61, 24251 };
mt19937 eng(time(0));
inline
ll randint(ll l, ll r) {
uniform_int_distribution<ll> dis(l, r);
return dis(eng);
}
inline
ll qpow(ll b, ll p, ll mod) {
ll res = 1;
while (p) {
if (p & 1) res = (lll)res * b % mod;
b = (lll)b * b % mod, p >>= 1;
}
return res;
}
inline
bool check(ll a, ll p) {
ll s = p - 1, k;
for (; ~s & 1; s >>= 1);
for (k = qpow(a, s, p); s != p - 1 && k != 1 && k != p - 1; k = (lll)k * k % p, s <<= 1);
return k == p - 1 || s & 1;
}
inline
bool isprime(ll n) {
if (n == 1) return 0;
for (int i = 0; i < 7; i++) {
if (n == prime[i]) return 1;
if (n % prime[i] == 0) return 0;
if (!check(prime[i], n)) return 0;
}
for (int i = 1; i <= 10; i++) if (!check(randint(2, n - 1), n)) return 0;
return 1;
}
inline
ll pollard_rho(ll n) {
if (n == 4) return 2;
if (isprime(n)) return n;
for (ll c, t, r, p, q; ;) {
c = randint(1, n - 1), t = 0, r = 0, p = 1, q;
auto f = [=](ll x) { return ((lll)x * x + c) % n; };
do {
for (int i = 0; i < 128; ++i) {
t = f(t), r = f(f(r));
if (t == r || (q = (lll)p * abs(t - r) % n) == 0) break; p = q;
}
ll d = __gcd(p, n); if (d > 1) return d;
} while (t != r);
}
}
unordered_map<ll, ll> mp;
ll get(ll x) {
if (mp[x]) return mp[x];
ll k = pollard_rho(x);
return mp[x] = k == x ? x : mp[x] = max(get(k), get(x / k));
}
inline
void print(lll n) {
if (n < 10) return putchar(n ^ '0'), void();
print(n / 10), putchar(n % 10 ^ '0');
}
inline
ll solve(ll n) {
lll res = (lll)n * n;
for (ll k = get(n); ; k = get(n)) {
for (res -= res / k / k; n % k == 0; n /= k);
if (n == 1) break;
}
mp.clear();
return res % mod;
}
}
namespace Sub7 {
inline
ll calc(ll n) {
ll ans = 114;
ans = (ans * n + 514) % mod;
ans = (ans * n + 1919) % mod;
ans = (ans * n + 810) % mod;
return ans;
}
inline
ll solve(ll n) {
ll ans = 1;
for (ll i = 2, k; i <= n / i; i++) {
for (k = 1; n % i == 0; n /= i, k *= i);
if (k > 1) ans = ans * calc(k) % mod;
}
if (n > 1) ans = ans * calc(n) % mod;
return ans;
}
}
namespace Sub8{
inline
ll solve(ll n){
return n*n%3;
}
}
typedef ll(*funcs)(ll);
funcs solve[9]={
Sub0::solve,Sub1::solve,Sub2::solve,Sub3::solve,Sub4::solve,Sub5::solve,Sub6::solve,Sub7::solve,Sub8::solve
};
ll n;
int t,id;
int main(){
scanf("%d",&k);
for(int i=1;i<=k;i++)scanf("%*d%lld",&f[i]);
for(scanf("%d%d",&t,&id);t--;scanf("%lld",&n),printf("%lld\n",solve[id](n)));
}
制作不易,给个关注吧哥!