当前位置: 首页 > ops >正文

LG P9990 [Ynoi Easy Round 2023] TEST_90 Solution

Description

给定序列 a = ( a 1 , a 2 , ⋯ , a n ) a=(a_1,a_2,\cdots,a_n) a=(a1,a2,,an).
定义 f ( l , r ) = ∣ { a i : i ∈ [ l , r ] } ∣ f(l,r)=|\{a_i:i\in[l,r]\}| f(l,r)={ai:i[l,r]}.
给定 m m m 次询问 ( l , r ) (l,r) (l,r),你要求出 ∑ l ≤ s ≤ t ≤ r ( f ( s , t ) m o d 2 ) \sum\limits_{l\le s\le t\le r}(f(s,t)\bmod 2) lstr(f(s,t)mod2).

Limitations

1 ≤ n , m ≤ 10 6 1\le n,m\le 10^6 1n,m106
1 ≤ a i , l , r ≤ n 1\le a_i,l,r\le n 1ai,l,rn
3 s , 512 MB 3\text{s},512\text{MB} 3s,512MB

Solution

在线做是做不了的,离线下来,挂在 r r r 上扫描线.
l s t i lst_i lsti 表示 i i i 前上一个 a i a_i ai 的出现位置.
考虑加入 a i a_i ai 后的影响,区间 [ l , i ] [l,i] [l,i] 的颜色数奇偶性会改变,其中 l ∈ ( l s t i , i ] l\in(lst_i,i] l(lsti,i].
显然这就是历史和,现在只需一个支持区间异或 1 1 1,区间历史和的 ds.

考虑线段树,节点上维护 1 1 1 的个数 cnt \textit{cnt} cnt 与历史和 his \textit{his} his,以及异或标记 rev \textit{rev} rev 0 / 1 0/1 0/1 的历史和更新标记 tag 0 / 1 \textit{tag}_{0/1} tag0/1.
这些都是容易直接维护的(具体见代码),于是做完了,时间复杂度 O ( ( n + m ) log ⁡ n ) O((n+m)\log n) O((n+m)logn).
注意要先下传异或标记,否则答案会错,以及开 long long 和常数问题.

Code

3.64 KB , 11.96 s , 153.59 MB (in total, C++20 with O2) 3.64\text{KB},11.96\text{s},153.59\text{MB}\;\texttt{(in total, C++20 with O2)} 3.64KB,11.96s,153.59MB(in total, C++20 with O2)

#include <bits/stdc++.h>
using namespace std;using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;template<class T>
bool chmax(T &a, const T &b){if(a < b){ a = b; return true; }return false;
}template<class T>
bool chmin(T &a, const T &b){if(a > b){ a = b; return true; }return false;
}namespace fastio {}     // By pystraf
using fastio::read;
using fastio::write;namespace seg_tree {inline int ls(int u) { return 2 * u + 1; }inline int rs(int u) { return 2 * u + 2; }struct Node {int l, r, len, cnt;i64 his, tag0 = 0, tag1 = 0;bool rev = false;};struct SegTree {vector<Node> tr;inline SegTree() {}inline SegTree(int n) : tr(n << 1) { build(0, 0, n - 1); }inline void pushup(int u, int mid) {tr[u].his = tr[ls(mid)].his + tr[rs(mid)].his;tr[u].cnt = tr[ls(mid)].cnt + tr[rs(mid)].cnt;}inline void neg(int u) {tr[u].rev ^= 1;swap(tr[u].tag0, tr[u].tag1);tr[u].cnt = tr[u].len - tr[u].cnt;}inline void apply(int u, i64 t0, i64 t1) {tr[u].his += t1 * tr[u].cnt + t0 * (tr[u].len - tr[u].cnt);tr[u].tag0 += t0, tr[u].tag1 += t1;}inline void pushdown(int u, int mid) {if (tr[u].rev) {neg(ls(mid)), neg(rs(mid));tr[u].rev = false;}if (tr[u].tag0 == 0 && tr[u].tag1 == 0) return;apply(ls(mid), tr[u].tag0, tr[u].tag1);apply(rs(mid), tr[u].tag0, tr[u].tag1);tr[u].tag0 = tr[u].tag1 = 0;}void build(int u, int l, int r) {tr[u].l = l, tr[u].r = r;tr[u].len = r - l + 1;if (l == r) return;const int mid = (l + r) >> 1;build(ls(mid), l, mid), build(rs(mid), mid + 1, r);}void negate(int u, int l, int r) {if (l > r) return;if (l <= tr[u].l && tr[u].r <= r) return neg(u);const int mid = (tr[u].l + tr[u].r) >> 1;pushdown(u, mid);if (l <= mid) negate(ls(mid), l, r);if (r > mid) negate(rs(mid), l, r);pushup(u, mid);}i64 query(int u, int l, int r) {if (l <= tr[u].l && tr[u].r <= r) return tr[u].his;const int mid = (tr[u].l + tr[u].r) >> 1;i64 res = 0;pushdown(u, mid);if (l <= mid) res += query(ls(mid), l, r);if (r > mid) res += query(rs(mid), l, r);return res;}};
}
using seg_tree::SegTree;
using pii = pair<int, int>;signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);const int n = read<int>();vector<int> a(n), lst(n), mp(n, -1);for (int i = 0; i < n; i++) {a[i] = read<int>(), a[i]--;lst[i] = mp[a[i]];mp[a[i]] = i;}const int m = read<int>();vector<vector<pii>> adj(n);for (int i = 0, l, r; i < m; i++) {l = read<int>(), r = read<int>(), l--, r--;adj[r].emplace_back(l, i);}SegTree sgt(n);vector<i64> ans(m);for (int i = 0; i < n; i++) {sgt.negate(0, lst[i] + 1, i);sgt.apply(0, 0, 1);for (auto [j, id] : adj[i]) ans[id] = sgt.query(0, j, i);}for (int i = 0; i < m; i++) {write(ans[i]);putchar_unlocked('\n');}return 0;
}
http://www.xdnf.cn/news/12182.html

相关文章:

  • 风机下引线断点检测算法实现
  • 免费wordpress模板下载
  • Astro深度解析:颠覆传统的前端架构革命,打造极致性能的现代Web应用
  • KMP 算法中 next 数组的构建函数 get_next
  • linux-------------------------进程间通信(上)
  • QMetaObject::invokeMethod调用失败
  • 摄像机ISP处理流程
  • 【面经分享】京东
  • springboot实现查询学生
  • Spring @Scheduled vs XXL-JOB vs DolphinScheduler vs Airflow:任务调度框架全景对比
  • 电子电路:什么是扩散电容?
  • PC 360安全浏览器
  • Spring Boot + MyBatis 集成支付宝支付流程
  • Hive的Parquet格式优化方法
  • AI应用工程师面试
  • html+css+js趣味小游戏~MissileGame街机挑战(附源码)
  • Hive SQL常见操作
  • 人工智能--大型语言模型的存储
  • 窗口聚合窗口聚合
  • YOLOv11 | 注意力机制篇 | 混合局部通道注意力MLCA与C2PSA机制
  • 【photoshop】专色浓度和专色密度
  • Python[数据结构及算法 --- 栈]
  • Mobile App UI自动化locator
  • 【数据结构】树形结构--二叉树(二)
  • JavaSec-XSS
  • 深入理解Java多态性:原理、实现与应用实例
  • SpringBoot使用dynamic配置多数据源时使用@Transactional事务在非primary的数据源上遇到的问题
  • 基于LocalAI与cpolar技术协同的本地化AI模型部署与远程访问方案解析
  • 通过SAE实现企业应用的云上托管
  • CICD实战(一) -----Jenkins的下载与安装