P8264 [Ynoi Easy Round 2020] TEST_100 题解
题意:P8264 [Ynoi Easy Round 2020] TEST_100。
简要题意:
范围:
分块,设块长为
假如我们可以预处理出每一个数经过每一个块最终的结果,那么我们就容易做到
首先,最暴力的直接枚举
我们不妨设有一个函数
按照这个过程 DFS,我们得到了一个
考虑优化,复杂度瓶颈显然在于
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std;
const int N = 1e5 + 5, M = 337;
int f[M][N];
int n, q, a[N];
int B;
int lans;
inline int get(int x)
{
return x / B;
}
inline int getL(int x)
{
return x * B;
}
int R;
int nowB;
void dfs(int l, int r, int k, int b, int u) // 定义域 [l,r]
{
if (l > r) return;
int zl = l * k + b, zr = r * k + b;
if (zl > zr) swap(zl, zr);
if (u == R)
{
for (int i = l; i <= r; i++)
{
f[nowB][i] = abs(i * k + b - a[R]);
}
return;
}
int p = a[u];
if (p > zr) // x -> p - x
{
dfs(l, r, -k, p - b, u + 1);
}
else if (p < zl)
{
dfs(l, r, k, b - p, u + 1);
}
else
{
int place = (p - b);
if (k >= 1)
{
int mid = place / k;
// [l, mid], (mid, r]
if (mid - l >= r - mid)
{
dfs(l, mid, -k, p - b, u + 1);
int nj = mid - 1;
for (int i = mid + 1; i <= r; i++)
{
f[nowB][i] = f[nowB][nj];
nj--;
}
}
else
{
dfs(mid, r, k, b - p, u + 1);
int nj = mid + 1;
for (int i = mid - 1; i >= l; i--)
{
f[nowB][i] = f[nowB][nj];
nj++;
}
}
}
else
{
int mid = place / k;
// [mid,r], [l,mid)
if (r - mid >= mid - l)
{
dfs(mid, r, -k, p - b, u + 1);
int nj = mid + 1;
for (int i = mid - 1; i >= l; i--)
{
f[nowB][i] = f[nowB][nj];
nj++;
}
}
else
{
dfs(l, mid, k, b - p, u + 1);
int nj = mid - 1;
for (int i = mid + 1; i <= r; i++)
{
f[nowB][i] = f[nowB][nj];
nj--;
}
}
}
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
B = sqrt(n);
int maxn = get(n);
memset(f, -1, sizeof f);
for (int i = 0; i <= maxn; i++)
{
int l = max(1, getL(i));
int r = min(n, getL(i + 1) - 1);
R = r;
nowB = i;
dfs(0, (int)1e5, 1, 0, l);
}
while (q--)
{
int l, r, v;
cin >> l >> r >> v;
l ^= lans, r ^= lans, v ^= lans;
if (get(l) == get(r))
{
int res = v;
for (int i = l; i <= r; i++) res = abs(res - a[i]);
cout << (lans = res) << "\n";
}
else
{
int gl = get(l), gr = get(r);
int res = v;
for (int i = l; i <= getL(gl + 1) - 1; i++) res = abs(res - a[i]);
for (int i = gl + 1; i < gr; i++) res = f[i][res];
for (int i = getL(gr); i <= r; i++) res = abs(res - a[i]);
cout << (lans = res) << "\n";
}
}
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现