NOIP 2023 模拟赛五 题解
A. [NOIP 2023 模拟赛五 By FXT A] 简单数学题
summarization
给出一个值域为 的正整数序列 ,序列中的数各不相同,求出使 为完全平方数的 的对数。
solution
实际上就是求 的 ,其中 需要在序列中存在。
变形为 ,考虑 的所有成对因数。
枚举 ,分解 ,根据 ,求出 ,最后统计答案。
由于枚举 太慢,考虑枚举因数 ,再枚举 的倍数
code
CI N = 1e6; int n, m, Tng[N + 5];
int main () {
RI i, j; for (Read (n, m), i = 1; i <= n; ++ i) {int x; Read (x); ++ Tng[x];}
ll ans = 0; for (i = 1; i <= N; ++ i) for (j = i; j <= N; j += i) {
int minn = min (i, j / i), maxx = max (i, j / i); if ((maxx - minn) % 2 == 0) ans += Tng[j] * Tng[(maxx - minn) / 2];
} ans /= 2; printf ("%lld\n", ans);
return 0;
}
B. [NOIP 2023 模拟赛五 By FXT B] 简单第三题
summarization
给出一个 到 的排列,你需要求出有多少个区间 ,满足这个区间的值是连续的。比如 是一个合法的区间,而 不是。()
solution1
考虑分治,将 范围的答案拆为 的答案和跨越 的连续的区间的个数,所以只需 求出在 范围内跨越 的连续的区间的个数。
首先,对于一个区间 是连续的,它的充要条件是
所以考虑预处理出两个数组 。 表示在 范围内, 区间的后缀最大值和在 范围内, 区间的前缀最大值。 同理。
那么对于 中一个区间 ,成为连续区间的条件变为:
考虑分类讨论 和 的取值情况。
一、
发现 ,枚举 判断合法情况即可
二、
同一。
三、
发现 。先固定 ,观察满足此情况时的不等条件:
由于 单调不减, 单调不增,所以满足上式的 一定在一个区间 中,其中 满足 。
当 左移一位后, 增加或不变, 减小或不变。发现 都需要向右移以满足新的不等条件。
于是将 从 一位一位移到 ,过程中维护 取值的区间,将在区间范围内的 的 加入桶中,查询 即可。桶的更新只需要在移动 时加入一个或删除一个即可。
四、
同三。
复杂度
分治算法总复杂度
code1
CI N = 3e5; int n, a[N + 5], mx[N + 5], mn[N + 5], Tng[N * 3 + 5]; ll ans = 0;
void solve (int L, int R) {
RI i, j; if (L == R) return ; int mid = (L + R) >> 1; solve (L, mid); solve (mid + 1, R); mx[mid] = mn[mid] = a[mid]; mx[mid + 1] = mn[mid + 1] = a[mid + 1];
for (i = mid - 1; i >= L; -- i) mx[i] = max (mx[i + 1], a[i]), mn[i] = min (mn[i + 1], a[i]);
for (i = mid + 2; i <= R; ++ i) mx[i] = max (mx[i - 1], a[i]), mn[i] = min (mn[i - 1], a[i]);
for (i = L; i <= mid; ++ i) {j = i + mx[i] - mn[i]; if (j > mid && j <= R && mx[i] > mx[j] && mn[i] < mn[j]) ++ ans;}
for (j = mid + 1; j <= R; ++ j) {i = j - mx[j] + mn[j]; if (i <= mid && i >= L && mx[i] < mx[j] && mn[i] > mn[j]) ++ ans;}
int l = mid + 1, r = mid + 1; for (i = mid; i >= L; -- i) {
W (r <= R && mx[r] < mx[i]) ++ Tng[mn[r] + r + N], ++ r;
W (l < r && mn[l] > mn[i]) -- Tng[mn[l] + l + N], ++ l;
ans += Tng[mx[i] + i + N];
} W (l < r) -- Tng[mn[l] + l + N], ++ l;
l = mid, r = mid; for (j = mid + 1; j <= R; ++ j) {
W (l >= L && mx[l] < mx[j]) ++ Tng[mn[l] - l + N], -- l;
W (l < r && mn[r] > mn[j]) -- Tng[mn[r] - r + N], -- r;
ans += Tng[mx[j] - j + N];
} W (l < r) -- Tng[mn[r] - r + N], -- r;
}
int main () {
RI i, j; for (Read (n), i = 1; i <= n; ++ i) Read (a[i]); solve (1, n); printf ("%lld\n", ans + n);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】