NOI模拟(10.29)T3 颜色
来源:互联网 发布:rimworld mac a14 编辑:程序博客网 时间:2024/05/29 17:20
颜色
题目背景:
10.29 NOI模拟T3
分析:树状数组 + 线段树 + set or 带修莫队 or 分块
第一眼带修莫队,思索了一下觉得貌似复杂度真的非常不稳啊······选择另辟蹊径,然后发现了比较稳的树套树做法,首先我们对于每一个位置记录其pre[i],表示上一个出现颜色c[i]的位置是pre[i],那么显然,对于一段区间l ~ r的询问,答案就是所有pre小于l - 1的地方的权值和,这个可以考虑用主席树维护,好了,如果没有修改操作的话,我们就可以用主席树一个log搞过去了,现在考虑修改操作,为了让修改不是nlog,那么我们直接在外层套一个树状数组,这样可以是修改和询问全部变成log2n,然后考虑修改的具体操作,显然我们需要快速查找某一位置的上一个颜色x出现的位置和下一个颜色x的出现位置,我们直接对每一个颜色开一个set,然后每一次lower_bound查询位置即可。
Source:
/*created by scarlyw*/#include <cstdio>#include <string>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#include <cctype>#include <vector>#include <set>#include <queue>#include <ctime>const int MAXN = 100000 + 10;int n, m, t, x, y, cnt;int c[MAXN], w[MAXN], last[MAXN];std::set<int> color[MAXN];std::set<int> :: iterator it, pre, suc;int root[MAXN];struct node {int left, right, sum;} tree[MAXN * 300];inline void read_in() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i) scanf("%d", &c[i]);for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);}inline void insert(int &cur, int l, int r, int pos, int w) {if (cur == 0) cur = ++cnt;tree[cur].sum += w;if (l == r) return ;int mid = l + r >> 1;if (pos <= mid) insert(tree[cur].left, l, mid, pos, w);else insert(tree[cur].right, mid + 1, r, pos, w);}inline int query(int cur, int l, int r, int ql, int qr) {if (ql <= l && r <= qr) return tree[cur].sum;int mid = l + r >> 1;int ret = 0;if (ql <= mid) ret += query(tree[cur].left, l, mid, ql, qr);if (qr > mid) ret += query(tree[cur].right, mid + 1, r, ql, qr);return ret;}inline int lowbit(int i) {return i & -i;}inline void insert(int i, int pos, int w) {for (; i <= n; i += lowbit(i)) insert(root[i], 0, n, pos, w);}inline void query(int l, int r) {int ans = 0;for (int i = r; i > 0; i -= lowbit(i)) ans += query(root[i], 0, n, 0, l - 1);for (int i = l - 1; i > 0; i -= lowbit(i))ans -= query(root[i], 0, n, 0, l - 1);printf("%d\n", ans);}inline void modify(int pos, int x) {int u = c[pos];if (u == x) return ;it = pre = suc = color[u].lower_bound(pos), pre--, suc++;insert(pos, *pre, -w[u]);if (suc != color[u].end()) insert(*suc, pos, -w[u]), insert(*suc, *pre, w[u]);color[u].erase(it), color[x].insert(pos), c[pos] = x;it = pre = suc = color[x].lower_bound(pos), pre--, suc++;insert(pos, *pre, w[x]);if (suc != color[x].end()) insert(*suc, *pre, -w[x]), insert(*suc, pos, w[x]);}inline void solve_tree() {for (int i = 1; i <= n; ++i) color[i].insert(0);for (int i = 1; i <= n; ++i)color[c[i]].insert(i), insert(i, last[c[i]], w[c[i]]), last[c[i]] = i;}inline void solve_query() {while (m--) {scanf("%d%d%d", &t, &x, &y);if (t == 1) modify(x, y);else query(x, y);}}int main() {freopen("color.in", "r", stdin);freopen("color.out", "w", stdout);read_in();solve_tree();solve_query();return 0;}
阅读全文
0 0
- NOI模拟(10.29)T3 颜色
- NOI模拟(10.29)T1 管道
- NOI模拟(10.29)T2 棋盘
- NOI题库(1.12.T3)甲流病人初筛
- NOI 模拟试题(一)
- NOI 模拟试题(二)
- NOI 模拟试题(三)
- 【NOIP 模拟题】[T3] 约会(lca)
- NOIP模拟(10.19)T3 放盒子
- NOIP模拟(10.20)T3 裁剪表格
- NOIP模拟(20171023)T3 拆网线
- NOIP模拟(10.22)T3 树
- NOIP模拟(10.23)T3 拆网线
- NOIP模拟(10.24)T3 Math
- NOIP模拟(20171024)T3 数学
- NOIP模拟(20171026)T3 大逃杀
- NOIP模拟(10.26)T3 大逃杀
- NOIP模拟(10.27)T3 心灵治愈
- 连接数据库错误
- Web前端开发最佳实践总结三:CSS最佳实践
- 椒盐噪声的图片 利用中值滤波效果好
- 单例模式的基本运用
- 设计模式之观察者模式
- NOI模拟(10.29)T3 颜色
- [地图]仿射变换矩阵
- maven创建eclipse工程
- 2017.10.30
- Django Admin管理工具
- centos7 javaweb 链接中文请求tomcat乱码问题解决
- LeetCode110. Balanced Binary Tree
- NLP07-Gensim源码简析[MmCorpus&SvmLightCorpus]
- CSS文件在jsp 文件中应该放的位置