Loj #6284. 数列分块入门 8
2021/10/9 23:05:49
本文主要是介绍Loj #6284. 数列分块入门 8,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Description
Loj传送门
Solution
个人认为是 \(Loj\) 上这几道分块题中比较好的一道题。
对于这道题,我们对于每一块打一个 \(lazy\) 标记,表示当前块是否被完整赋过值,即全部赋值为 \(c\)。
修改时,整块的直接修改 \(lazy\) 标记,两头多余的部分暴力修改原数组。
注意: 整个块都要重新赋值一遍。
-
在查询范围内的:赋值为 \(c\)。
-
在查询范围外的:赋值为 \(lazy\) 标记。
然后把该块的 \(lazy\) 标记赋值为 \(INF\)。
查询时,整块的直接判断求和,并把 \(lazy\) 改为 \(c\);两头的暴力枚举判断,同时在有 \(lazy\) 标记时进行上述修改。
修改的部分我对着数据调了好久 \(QwQ\)。
经验:一定要想好了在写,不然会漏掉许多细节。
具体见代码吧。
Code
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <cmath> #define INF 1e18 #define ll long long #define ri register int using namespace std; inline ll read(){ ll x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar(); return x * f; } const ll N = 1e5 + 10; ll n, B, tot; ll a[N], be[N], ml[N], mr[N], lazy[N]; inline void build(){ B = sqrt(n); tot = n / B + (B * B != n); for(ri i = 1; i <= n; i++) be[i] = (i - 1) / B + 1; for(ri i = 1; i <= tot; i++){ lazy[i] = INF; ml[i] = (i - 1) * B + 1; mr[i] = i * B; } mr[tot] = n; } inline ll calc(int l, int r, int c){ ll res = 0; if(lazy[be[l]] == INF){ for(ri i = l; i <= r; i++) res += (a[i] == c), a[i] = c; }else{ if(lazy[be[l]] == c) res += (r - l + 1); else{ for(int i = l; i <= r; i++) a[i] = c; for(int i = ml[be[l]]; i < l; i++) a[i] = lazy[be[l]]; for(int i = r + 1; i <= mr[be[l]]; i++) a[i] = lazy[be[l]]; lazy[be[l]] = INF; } } return res; } inline ll solve(ll l, ll r, ll c){ if(be[l] == be[r]) return calc(l, r, c); ll res = 0; for(ll i = be[l] + 1; i <= be[r] - 1; i++){ if(lazy[i] == INF){ for(ri j = ml[i]; j <= mr[i]; j++) res += (a[j] == c); }else if(lazy[i] == c) res += B; lazy[i] = c; } res += calc(l, mr[be[l]], c) + calc(ml[be[r]], r, c); return res; } signed main(){ freopen("#6284.in", "r", stdin); freopen("#6284.out", "w", stdout); n = read(); for(ri i = 1; i <= n; i++) a[i] = read(); build(); for(ri i = 1; i <= n; i++){ ri l = read(), r = read(), c = read(); printf("%lld\n", solve(l, r, c)); } return 0; }
End
这篇关于Loj #6284. 数列分块入门 8的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南