洛谷 P10704 救赎(Redemption)

洛谷传送门

不依赖 ai109 的做法。

bx 为有多少个 i 使得 ai=x

设一个阈值 B。当 maiaj>Baiaj<mB,可以直接枚举 aiaj 然后利用 b 数组统计。这部分时间复杂度为 O(mBlnmB)

maiajB 时,统计 maiaj 之和可以转化为对于一个整数 k[1,B],有多少对 (i,j) 满足 xmaiajxaiajm。可以排序后双指针统计。这部分时间复杂度为 O(nB)

总时间复杂度为 O(mBlnmB+nB)。取 B=350 可以通过。

code
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 1000100;
const int N = 30000000;
const ll mod = 998244353;
ll n, m, a[maxn], b[N + 5];
void solve() {
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
if (a[i] <= N) {
++b[a[i]];
}
}
sort(a + 1, a + n + 1);
ll ans = 0;
for (int i = 1; i <= N; ++i) {
if (!b[i]) {
continue;
}
for (int j = 1; i * j <= N; ++j) {
if (b[j]) {
ll x = m / i / j;
if (x <= 350) {
continue;
}
x %= mod;
ans = (ans + b[i] * b[j] % mod * x) % mod;
}
}
}
for (int x = 1; x <= 350; ++x) {
for (int i = n, j = 0, k = 1; i; --i) {
while (j < n && x * a[i] * a[j + 1] <= m) {
++j;
}
while (k <= n && a[i] * a[k] * 351 <= m) {
++k;
}
ans += j - k + 1;
}
}
printf("%lld\n", ans % mod);
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
posted @   zltzlt  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2023-07-07 20230707 讲题
点击右上角即可分享
微信分享提示