bzoj1483: [HNOI2009]梦幻布丁(链表+启发式合并)
题目大意:一个序列,两种操作。
①把其中的一种数修改成另一种数
②询问有多少段不同的数如1 2 2 1为3段(1 / 2 2 / 1)。
昨晚的BC的C题和这题很类似,于是现学现写居然过了十分开心。
先把初始序列的答案统计出来,然后把每种数都用一个链表串起来,修改的时候把两种数的链表合并一下。修改答案的时候,比如把数x全部修改为数y,那么把数x的链表遍历一次,某个数x左边有y就把答案-1,右边有y也-1。
接下来是重点了:要把链表长度小的接在链表长度大的后面,才能做到nlogn。因为把链表长度小的接在大的后面,新链表长度一定>=原长度小的链表的长度的两倍,最多变长logn次,所以均摊下来每次修改效率O(logn),总复杂度为O(nlogn)。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000005
using namespace std;
int a[maxn],size[maxn],next[maxn],last[maxn],pos[maxn],f[maxn],ans,n,m;
int main()
{
scanf("%d %d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]!=a[i-])ans++;
pos[a[i]]=a[i];
if(!f[a[i]])f[a[i]]=i;
size[a[i]]++;next[i]=last[a[i]];last[a[i]]=i;
}
for(int i=;i<=m;i++)
{
int opt;
scanf("%d",&opt);
if(opt==)
{
int x,y;
scanf("%d %d",&x,&y);
if(x==y)continue;
if(size[pos[x]]>size[pos[y]])swap(pos[x],pos[y]);
x=pos[x];y=pos[y];
if(!size[x])continue;
for(int i=last[x];i;i=next[i])
{
if(a[i+]==y)ans--;
if(a[i-]==y)ans--;
}
for(int i=last[x];i;i=next[i])a[i]=y;
size[y]+=size[x];size[x]=;
next[f[x]]=last[y];last[y]=last[x];last[x]=f[x]=;
}else printf("%d\n",ans);
}
}
bzoj1483: [HNOI2009]梦幻布丁(链表+启发式合并)的更多相关文章
- 【BZOJ1483】[HNOI2009]梦幻布丁 链表+启发式合并
[BZOJ1483][HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2 ...
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
- BZOJ 1483: [HNOI2009]梦幻布丁 [链表启发式合并]
1483: [HNOI2009]梦幻布丁 题意:一个带颜色序列,一种颜色合并到另一种,询问有多少颜色段 一种颜色开一个链表,每次遍历小的合并到大的里,顺带维护答案 等等,合并方向有规定? 令col[x ...
- bzoj1483: [HNOI2009]梦幻布丁(vector+启发式合并)
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4022 Solved: 1640[Submit][Statu ...
- bzoj 1483: [HNOI2009]梦幻布丁 (链表启发式合并)
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...
- 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)
题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
- BZOJ 1483 梦幻布丁(链表+启发式合并)
给出一个长度为n的序列.支持两种操作: 1.把全部值为x的修改成y.2.询问序列有多少连续段. 我们可以对于每个值建立一个链表.对于操作1,则可以将两个链表合并. 对于操作2,只需要在每次合并链表的时 ...
- [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并)
[BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并) 题面 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1 ...
- 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]
题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...
随机推荐
- Appium Inspector定位元素与录制简单脚本
本次以微信为例, 使用Appium自带的Inspector定位工具定位元素, 以及进行最最最简单脚本的录制: capabilities = { "platformName": &q ...
- Spring 配置请求过滤器,编码格式设为UTF-8,避免中文乱码
<!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码--> <filter> <filter-name>springUtf8Encoding</fi ...
- JSP页面中文乱码问题
$.get()方法到服务器端中文乱码 在jsp页面使用encodeURI(“中文”),在服务器端进行解码 String name = req.getParameter("name" ...
- Python最长连续数列的O(n)解法
题目 输入一个乱序的连续数列,输出其中最长连续数列长度,要求算法复杂度为 O(n) . 输入样例 100,4,200,1,3,2 54,55,300,12 1 5,4,3,2,1 1,2,3,4,5, ...
- javascript的原始类型(primitive type)之间的关系。
1:有5种primitive type,分别是Undefined.Null.Boolean.Number 和 String. 2: 3:alert(null == undefined);结果为true ...
- from module import 和 import 的区别
最近在用codecademy学python,遇到一些题目错误,小小记录一下 如from math import sqrt是把sqrt作为本文件的方法导入进来了,使用的时候只需要直接调用sqrt. 而如 ...
- Java 变量和输入输出
一些重要知识 一个源文件里只能有一个public类,其它类数量不限.文件名与public类名相同 JAVA程序严格区分大小写 JAVA应用程序的执行入口是main方法固定写法:public stati ...
- HTTP 请求头 & 响应头
HTTP请求头概述 HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST).如有必要,客户程序还可以选择发送其他的请求头.大多数请求头并不是必需的, 但Co ...
- 内部网关协议RIP 路由选择算法(距离向量)
RIP是一种基于距离向量的路由选择协议 RIP的距离就是指的跳数,没经过一个路由,就是一跳,RIP允许一跳路径最多经过15个路由器,所以16个的话就相当于不可以到达了 RIP协议的特点: 1:仅和相邻 ...
- 将MathType公式转换为LaTex格式
LaTex编辑公式不够直观,常常会因为结构复杂导致数据或者符号出错,使用MathType编辑公式后再直接转换成LaTex代码可以避免这个问题. 一.首先在MathType中编辑公式 二.然后点击参数— ...