「Gym-102803H」Hate That You Know Me
题目概述
给定
思路&&做法
首先观察到题目需要求从
可以发现对于
但我们显然不能枚举
对于
/*
address:https://vjudge.net/problem/Gym-102803H
*/
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int N = 1e6 + 5;
int a, b;
ULL n;
inline ULL calc(ULL l, ULL r, int x) {
if (x == 0) return r - l + 1;
if (x == 1) return (l + r) * (r - l + 1) / 2;
if (x == 2) return (r * (r + 1) * (2 * r + 1) / 6) - ((l - 1) * (l) * (l * 2 - 1) / 6);
if (x == 3) return (r * (r + 1) / 2) * (r * (r + 1) / 2) - (l * (r - 1) / 2) * (l * (r - 1) / 2);
}
int main() {
scanf("%d%d%llu", &a, &b, &n);
ULL x = 0, y = 0;
for (ULL L = 1, R = 1;n / L;L = R + 1) {
R = n / (n / L);
x += calc(L, R, a) * (n / L);
y += calc(L, R, b) * (n / L);
}
printf("%llu", x ^ y);
return 0;
}
完结撒花……了吗?
如果此时你交一发,会发现自己神奇的
仔细观察,代码中计算的部分是有除法的,在取模的情况下不能进行除法,然后我们又悲催地发现模数不是质数,还不保证互质,所以乘法逆元不可行。但我们知道,是在乘完取模后不能除,而我们在除的时候是在计算一个固定值,并不是边乘边取,所以我们可以在乘上两个数取模之前先把要除的数除掉就行。
/*
address:https://vjudge.net/problem/Gym-102803H
AC 2025/2/8 14:53
*/
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int N = 1e6 + 5;
int a, b;
ULL n;
inline ULL calc(ULL l, ULL r, int x) {
ULL ret = 1;
if (x == 0) return r - l + 1;
if (x == 1) {
ULL x = l + r, y = r - l + 1;
if (!(x & 1)) x /= 2;
else y /= 2;
return x * y;
}
if (x == 2) {
ULL x = r, y = r + 1, z = 2 * r + 1;
if (x % 2 == 0) x /= 2;
else if (y % 2 == 0) y /= 2;
else z /= 2;
if (x % 3 == 0) x /= 3;
else if (y % 3 == 0) y /= 3;
else z /= 3;
ret = x * y * z;
x = l - 1, y = l, z = l * 2 - 1;
if (!(x & 1)) x /= 2;
else if (!(y & 1)) y /= 2;
else z /= 2;
if (x % 3 == 0) x /= 3;
else if (y % 3 == 0) y /= 3;
else z /= 3;
ret -= x * y * z;
return ret;
}
if (x == 3) {
if (r & 1) ret = ((r + 1) / 2) * ((r + 1) / 2) * r * r;
else ret = (r / 2) * (r / 2) * (r + 1) * (r + 1);
ULL del;
if (l & 1) del = ((l - 1) / 2) * ((l - 1) / 2) * l * l;
else del = (l / 2) * (l / 2) * (l - 1) * (l - 1);
ret -= del;
return ret;
}
}
int main() {
scanf("%d%d%llu", &a, &b, &n);
ULL x = 0, y = 0;
for (ULL L = 1, R = 1;n / L;L = R + 1) {
R = n / (n / L);
x += calc(L, R, a) * (n / L);
y += calc(L, R, b) * (n / L);
}
printf("%llu", x ^ y);
return 0;
}
这道题不难,就是中间要在取模前除有点坑。
分类:
其他算法 / 整除分块
标签:
整除分块
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现