【区间合并+贡献法】codeforces 1789 C. Serval and Toxel's Arrays
1.前后缀分解2.【前缀和+开区间二分】codeforces 1187 B. Letters Shop3.【字符串哈希+二分】AcWing 3508. 最长公共子串4.【二分+前缀和+后缀和】codeforces 2026 D. Sums of Segments5.【滑动窗口】codeforces 1290 A. Mind Control6.【三分】AcWing 3666. 士兵排阵7.【带权前缀和】codeforces 2044 H. Hard Demon Problem
8.【区间合并+贡献法】codeforces 1789 C. Serval and Toxel's Arrays
9.【离线+单调栈】AtCoder ABC379 F. Buildings 210.【前后缀分解】AtCoder ABC393 D.Swap to Gather题目
https://codeforces.com/problemset/problem/1789/C
题意
第一行输入一个正整数
对于每组测试用例:第一行输入两个正整数
保证初始数组,以及每次修改后的数组,都不包含重复元素,且对数组的修改是永久操作;
经过
...
要求计算出这个
题解
不妨假设有
分类讨论:
- 与含有元素
的其他一组数组进行组合,那么两两组合 只会贡献 次答案;若总的有 组数组具有元素 ,则只会贡献 次答案; - 与不含有元素
的其他数组进行组合,不妨假设其他数组共有 组,含有元素 的数组共有 组,那么会贡献 次答案,其中 。
综上所述,我们只需要维护出每个元素出现的区间(不妨用左闭右开区间),在最后进行区间合并,得到每个元素在全部数组中出现的次数,不妨假设次数为
参考代码
#include<bits/stdc++.h> #define PII pair<int, int> #define eb(x) emplace_back(x) using namespace std; typedef long long ll; constexpr int N = 2e5 + 7; int T, n, m, p, q; int a[N]; void solve() { ll ans = 0LL; cin >> n >> m; int w = m + 1; vector<PII> v[n + m + 1]; for (int i = 1; i <= n; ++ i) { cin >> a[i]; v[a[i]].eb(PII(0, w)); } for (int i = 1; i <= m; ++ i) { cin >> p >> q; v[a[p]].back().second = i; v[q].eb(PII(i, w)); a[p] = q; } for (int i = 1; i <= n + m; ++ i) { if (v[i].empty()) continue; ll len = 0LL; int l = v[i][0].first, r = v[i][0].second; for (int j = 1; j < v[i].size(); ++ j) { if (v[i][j].first == r) r = v[i][j].second; else { len += r - l; l = v[i][j].first; r = v[i][j].second; } } len += r - l; ans += (len * (len - 1) >> 1) + len * (w - len); } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); cin >> T; while (T --) { solve(); } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 【.NET】调用本地 Deepseek 模型