P9920 「RiOI-03」变换,反演

文章讲述了如何解决一道关于积性函数计算和模运算的编程题目,涉及不同解法分析。

提示:本题难度NOI/NOI+/CTSC较难,最好先学会方法再写。

题目背景

为了题目要求,我们对积性函数进行重定义:不保证 f(1)=1f(1)=1

题目描述

这是一道非传统题。

给定一个积性函数 f(d)f(d)。对于每一个测试点,我们会在附件中给出 g(n)=\sum_{d|n}f(d)g(n)=∑d∣n​f(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}Scoren\leqn≤k=k=t=t=
00\text{Epsilon}Epsilon5510^61061001001010
11\text{Division}Division5510^91091001001010
22\text{Unknown}Unknown5510^{18}1018111010
33\text{Random}Random101010^510510^510510^5105
44\text{Double}Double101010^91091001001010
55\text{Hack}Hack101010^9109316233162311
66\text{Square}Square151510^{18}101810010055
77\text{Poly}Poly202010^910910^5105100100
88\text{Thanks}Thanks202010^51054410^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)));
}

制作不易,给个关注吧哥!

源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔王 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 控制台粘贴代码并运行,获得类似的输出信息 部分即为所需复制的 Cookie,点击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压缩包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值