洛谷 3201 [HNOI2009]梦幻布丁 解题报告
3201 [HNOI2009]梦幻布丁
题目描述
\(N\)个布丁摆成一行,进行\(M\)次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为\(1,2,2,1\)的四个布丁一共有\(3\)段颜色.
输入输出格式
输入格式:
第一行给出\(N,M\)表示布丁的个数和好友的操作次数. 第二行\(N\)个数\(A_1,A_2,\dots,A_n\)表示第\(i\)个布丁的颜色.
从第三行起有\(M\)行,对于每个操作,若第一个数字是\(1\)表示要对颜色进行改变,其后的两个整数\(X,Y\)表示将所有颜色为\(X\)的变为\(Y\),\(X\)可能等于\(Y\).
若第一个数字为\(2\)表示要进行询问当前有多少段颜色,这时你应该输出一个整数.
输出格式:
针对第二类操作即询问,依次输出当前有多少段颜色.
说明
\(1<=n,m<=100,000,0<A_i,x,y<1,000,000\)
思路:对每个颜色维护一个平衡树,平衡树每个节点维护一个是否贡献,我设定的是与前驱是否相邻,然后维护子树贡献和。每次暴力启发式合并就可以了。
听说有链表\(O(n\log n)\)的高级做饭,但是我懒得看。
Code:
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#define ls ch[now][0]
#define rs ch[now][1]
const int N=1e5+10;
int sum[N],ch[N][2],val[N],d[N],siz[N],root[N*10],n,m;
void updata(int now){sum[now]=sum[ls]+sum[rs]+d[now],siz[now]=siz[ls]+siz[rs]+1;}
void split(int now,int k,int &x,int &y)
{
if(!now){x=y=0;return;}
if(now<=k)
x=now,split(rs,k,rs,y);
else
y=now,split(ls,k,x,ls);
updata(now);
}
int Merge(int x,int y)
{
if(!x||!y) return x|y;
if(val[x]<val[y])
{
ch[x][1]=Merge(ch[x][1],y);
updata(x);
return x;
}
else
{
ch[y][0]=Merge(x,ch[y][0]);
updata(y);
return y;
}
}
void Insert(int id,int now)
{
int x,y,z;
split(root[id],now,x,y);
split(x,now-2,x,z);
sum[now]=d[now]=z==0;
x=Merge(x,z);
split(y,now+1,z,y);
sum[z]=d[z]=0;
y=Merge(z,y);
root[id]=Merge(x,Merge(now,y));
}
void dfs(int id,int now)
{
if(!now) return;
dfs(id,ls),dfs(id,rs);
ls=rs=0,siz[now]=1,Insert(id,now);
}
int ans=0;
void merge(int x,int y)
{
if(x==y) return;
if(siz[root[x]]<siz[root[y]]) std::swap(root[x],root[y]);
ans-=sum[root[x]]+sum[root[y]];
dfs(x,root[y]);
root[y]=0,ans+=sum[root[x]];
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("dew.out","w",stdout);
scanf("%d%d",&n,&m);
for(int clo,i=1;i<=n;i++)
{
scanf("%d",&clo);
val[i]=rand(),siz[i]=1;
Insert(clo,i);
}
for(int i=1;i<=1000000;i++) ans+=sum[root[i]];
for(int op,x,y,i=1;i<=m;i++)
{
scanf("%d",&op);
if(op==1) scanf("%d%d",&x,&y),merge(y,x);
else printf("%d\n",ans);
}
return 0;
}
2018.12.12
洛谷 3201 [HNOI2009]梦幻布丁 解题报告的更多相关文章
- 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]
题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...
- 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)
题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
- 洛谷P3201 [HNOI2009]梦幻布丁
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
- 洛谷 P3201 [HNOI2009]梦幻布丁(启发式合并)
题面 luogu 题解 什么是启发式合并? 小的合并到大的上面 复杂度\(O(nlogn)\) 这题颜色的修改,即是两个序列的合并 考虑记录每个序列的\(size\) 小的合并到大的 存序列用链表 但 ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
- 洛谷 P2317 [HNOI2005]星际贸易 解题报告
P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...
- 洛谷 P3802 小魔女帕琪 解题报告
P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...
- 洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...
- 洛谷1303 A*B Problem 解题报告
洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...
随机推荐
- Tp框架之命名空间
命名空间,相当于虚拟目录 实现自动加载类的机制 初始命名空间:Library文件夹 初始命名空间下面有很多根命名空间: 1.Library里面的文件夹 2.APP的模块文件夹 在tp框架中,只有这两个 ...
- 使用Photon引擎进行unity网络游戏开发(一)——Photon引擎简介
使用Photon引擎进行unity网络游戏开发(一)--Photon引擎简介 Photon PUN Unity 网络游戏开发 Photon引擎简介: 1. 服务器引擎: 服 务 器 引 擎 介 绍 服 ...
- idea 模版之自定义类与方法注释
idea 模版之自定义类与方法注释 很多公司都有要求的代码注释规范,我们每新建类或者方法的时候从新复制粘贴很麻烦,而且容易粘错. 当然自定义模板还可以用到很多地方,比如系统自带的 sout就是syst ...
- Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
1. 摘要 训练深层的神经网络非常困难,因为在训练的过程中,随着前面层数参数的改变,每层输入的分布也会随之改变.这需要我们设置较小的学习率并且谨慎地对参数进行初始化,因此训练过程比较缓慢. 作者将这种 ...
- K-means + PCA + T-SNE 实现高维数据的聚类与可视化
使用matlab完成高维数据的聚类与可视化 [idx,Centers]=kmeans(qy,) [COEFF,SCORE,latent] = pca(qy); SCORE = SCORE(:,:); ...
- underscore.js源码解析(二)
前几天我对underscore.js的整体结构做了分析,今天我将针对underscore封装的方法进行具体的分析,代码的一些解释都写在了注释里,那么废话不多说进入今天的正文. 没看过上一篇的可以猛戳这 ...
- 20172305 2018-2019-1 《Java软件结构与数据结构》第八周学习总结
20172305 2018-2019-1 <Java软件结构与数据结构>第八周学习总结 教材学习内容总结 本周内容主要为书第十二章内容: 堆(附加属性的二叉树) 完全二叉树 (最小堆)对于 ...
- CS小分队第二阶段冲刺站立会议(5月29日)
昨日成果:昨天在为主界面设计自主添加应用快捷方式功能,连续遇到困难. 遇到的困难:1.string字符串数组无法在单击事件中使用,提示string无法在eventargs中检索,尝试了各种方式都不行 ...
- ERROR----java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
2013-4-28 13:17:57 org.apache.catalina.core.StandardContext filterStart 严重: Exception starting filte ...
- lintcode-248-统计比给定整数小的数的个数
248-统计比给定整数小的数的个数 给定一个整数数组 (下标由 0 到 n-1,其中 n 表示数组的规模,数值范围由 0 到 10000),以及一个 查询列表.对于每一个查询,将会给你一个整数,请你返 ...