UVA12003 Array Transformer
题意
给定一个序列
-
求区间
中严格小于 的数的个数。 -
单点修改。
解法
块内二分模板题。
考虑每一个块维护一个有序的 vector
或者其他容器,块内查询用 lower_bound
,块外暴力。单点修改时修改数组的值并且用
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define int long long
constexpr int N(3e5 + 5), M(585);
int n, m, u, len, a[N];
vector<int> p[M];
inline int get(int x)
{
if (x == 0) return 0;
return (x - 1) / len + 1;
}
inline int lplace(int x)
{
return (x - 1) * len + 1;
}
inline int rplace(int x)
{
return x * len;
}
signed main()
{
scanf("%lld%lld%lld", &n, &m, &u);
len = sqrt(n);
for (register int i(1); i <= n; ++i)
{
scanf("%lld", &a[i]);
p[get(i)].push_back(a[i]);
}
for (register int i(1); i <= len + 1; i++)
{
sort(p[i].begin(), p[i].end());
}
while (m--)
{
int l, r, v, pg, ans(0);
scanf("%lld%lld%lld%lld", &l, &r, &v, &pg);
if (get(l) == get(r))
{
for (int i(l); i <= r; i++) ans += a[i] < v;
}
else
{
int lp(get(l) + 1), rp(get(r) - 1);
for (int i(lp); i <= rp; i++)
{
vector<int>::iterator it = lower_bound(p[i].begin(), p[i].end(), v);
ans += (it - p[i].begin());
}
int lk(lplace(lp)), rk(rplace(rp));
for (int i(l); i < lk; i++) ans += a[i] < v;
for (int i(rk + 1); i <= r; i++) ans += a[i] < v;
}
int k(a[pg]);
a[pg] = u * ans / (r - l + 1);
*lower_bound(p[get(pg)].begin(), p[get(pg)].end(), k) = a[pg];
//cout << ans << endl;
sort(p[get(pg)].begin(), p[get(pg)].end());
}
for (int i(1); i <= n; i++) printf("%lld\n", a[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】