题目链接  rausen loves cakes

题意  给出一个序列和若干次修改和查询。修改为把序列中所有颜色为$x$的修改为$y$,

查询为询问当前$[x, y]$对应的区间中有多少连续颜色段。

    序列长度为$n$,总操作数为$q$,满足$1 <= n <= 10^{5}, 1 <= q <= 10^{5}$

初始化的时候若当前颜色和前一个位置的颜色不相等的时候则在这个位置的树状数组中打标记。

修改的时候,颜色权值数小的往大的合并,这样满足总合并复杂度为$O(nlogn)$,

若当前位置经过修改之后和前一个位置颜色相等则取消当前位置的标记,

若当前位置经过修改之后和后一个位置颜色相等则取消当前位置的后一个位置的标记,

注意最后统计答案的时候第要对第一个位置特判。

因为用到了set,所以总时间复杂度$O(nlog^{2}n)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL; const int N = 1e5 + 10;
const int M = 1e6 + 10; int T;
int ans;
int n, m;
int a[N], f[M];
int c[N];
set <int> s[M]; void update(int x, int val){
for (; x <= n; x += x & -x) c[x] += val;
} int query(int x){
if (x < 1) return 0;
int ret = 0;
for (; x; x -= x & -x) ret += c[x];
return ret;
} void solve(int x, int y){
for (auto u : s[x]){
if (a[u - 1] == y) update(u, -1);
if (a[u + 1] == y) update(u + 1, -1);
s[y].insert(u);
} for (auto u : s[x]) a[u] = y;
s[x].clear();
} int main(){ scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%d", a + i);
memset(f, 0, sizeof f);
memset(c, 0, sizeof c);
rep(i, 0, 1e6 + 1) s[i].clear();
rep(i, 1, n){
f[a[i]] = a[i];
if (a[i] ^ a[i - 1]) update(i, 1);
s[a[i]].insert(i);
} rep(i, 1, m){
int op, x, y;
scanf("%d", &op);
if (op == 1){
int x, y;
scanf("%d%d", &x, &y);
if (x == y) continue;
if (s[f[x]].size() > s[f[y]].size()) swap(f[x], f[y]);
x = f[x], y = f[y];
solve(x, y);
}
else{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", query(y) - query(x - 1) + (a[x] == a[x - 1]));
}
}
} return 0;
}

  

最新文章

  1. 整理Ajax的点点滴滴
  2. AlloyRenderingEngine入门
  3. tiny中文乱码问题,不过仅适用于windows,所以xml不可以出现中文
  4. JavaScript DOM编程艺术读书笔记(二)
  5. Go-Agent原理分析及FQ介绍
  6. Linux主流發行版本介紹
  7. tyvj3481 越狱
  8. JS中Date对象getYear()方法和getFullYear()方法区别
  9. 有趣的Node爬虫,数据导出成Excel
  10. 插入三层treeview代码
  11. js和jsp
  12. wm命令用法及LCD显示图标大小不正常时解决的方法
  13. PAT (Advanced Level) 1075. PAT Judge (25)
  14. python 函数返回多个参数的赋值方法
  15. 51单片机GPIO口模拟串口通信
  16. 【开讲啦】20181029 oracle教学笔记
  17. nio 阻塞 非阻塞 同步 异步
  18. 验证调用HttpServletResponse.getWriter().close()方法是否真的会关闭http连接
  19. 使用Python制作第一个爬虫程序
  20. 基于虹软人证核验 2.0 Android SDK开发集成入门

热门文章

  1. HDU 1506 Largest Rectangle in a Histogram(单调栈、笛卡尔树)
  2. IDEA配置好maven后新建maven项目一直build失败的解决方法
  3. iOS下单例模式实现(二)利用宏定义快速实现
  4. C#定时器,定时做什么事情
  5. 46、android studio第一次使用时卡在gradle下载怎么解决?
  6. Solr配置Ikanalyzer分词器
  7. server.xml属性概念
  8. 在Myeclipse8.5中安装findbugs方法
  9. c++ 中pair类模板的用法详解
  10. MySql数据库 - 4.可视化操作数据库