1483. [HNOI2009]梦幻布丁【平衡树-splay】
Description
Input
Output
针对第二类操作即询问,依次输出当前有多少段颜色.
Sample Input
1 2 2 1
2
1 2 1
2
Sample Output
1
学会启发式合并后,其实这个题就是裸题了
splay启发式合并,听起来很智能,只不过就是暴力将小splay上的点一个个insert到大splay上
这个题只需要将需要改的颜色的splay合并到目标颜色splay上就好了
(这个程序并没有从小的合并到大的,不过仍然很快,可能是数据太弱了)
只不过程序中有一些小细节需要注意就是了
细节详见code
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<algorithm>
- #define N (1000000+100)
- using namespace std;
- int Size[N],Key[N];//key[i]中存的是编号为i的颜色,用序列的编号大小来建splay,节点里存颜色
- int Father[N],Son[N][];
- int n,m,Root[N],ans,a[N];
- int flag;
- int Get(int x){return Son[Father[x]][]==x;}
- void Update(int x){Size[x]=Size[Son[x][]]+Size[Son[x][]]+;}
- void Clear(int x){Key[x]=Father[x]=Son[x][]=Son[x][]=Size[x]=;}
- void Rotate(int x)
- {
- int wh=Get(x);
- int fa=Father[x],fafa=Father[fa];
- Son[fa][wh]=Son[x][wh^];
- Father[fa]=x;
- if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
- Son[x][wh^]=fa;
- Father[x]=fafa;
- if (fafa) Son[fafa][Son[fafa][]==fa]=x;
- Update(fa);
- Update(x);
- }
- void Splay(int x,int &root)
- {
- for (int fa;fa=Father[x];Rotate(x))
- if (Father[fa])
- Rotate(Get(fa)==Get(x)?fa:x);
- root=x;
- }
- void Insert(int x,int color,int &root)
- {
- if (root==)
- {
- Size[x]=;
- Key[x]=color;
- root=x;
- return;
- }
- int now=root,fa=;
- while ()
- {
- fa=now;now=Son[now][x>now];
- if (now==)
- {
- Size[x]=;
- Key[x]=color;
- Father[x]=fa;
- Son[fa][x>fa]=x;
- Update(fa);
- Splay(x,root);
- return;
- }
- }
- }
- void Change(int x,int &root,int color)//唯一需要注意的函数,参数:(被拆的splay的当前节点,合并到的splay的根,需要改成什么颜色)。按中序遍历将要拆的splay一个个拆掉就好
- {
- if (Son[x][]) Change(Son[x][],root,color);
- int rson=Son[x][];//因为下面要clear x这个节点的信息,所以事先存一下
- int pre_color=Key[x];//同上
- if (!flag && Key[x]!=Key[x-]) flag=+(color==Key[x-]);//☆如果x是连续序列的开始,就把flag改成1。如果不仅是开始,还能和前一个连起来,flag再加一。(flag在连续序列结束的地方会用到)
- Clear(x);
- Insert(x,color,root);//插入到目标splay中
- if (Key[x]==Key[x+]) ans-=;//如果当前是连续序列的结束且这个点能和后面的颜色接上,ans--。
- if (Key[x+]!=pre_color) ans-=flag-,flag=;//如果这个点是结束,ans根据开头是否接上判断减不减。flag归零。
- if (rson) Change(rson,root,color);
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for (int i=;i<=n;++i)
- {
- scanf("%d",&a[i]);
- if (a[i]!=a[i-]) ans++;
- Insert(i,a[i],Root[a[i]]);
- }
- int opt,x,y;
- for (int i=;i<=m;++i)
- {
- scanf("%d",&opt);
- if (opt==)
- {
- scanf("%d%d",&x,&y);
- if (Root[x]== || x==y) continue;//如果当前颜色没有节点 或者 这次更改前后的颜色是一样的 就不用做了(因为做了会卡)
- Change(Root[x],Root[y],y);
- Root[x]=;
- }
- if (opt==) printf("%d\n",ans);
- }
- }
1483. [HNOI2009]梦幻布丁【平衡树-splay】的更多相关文章
- bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1818 Solved: 761[Submit][Status ...
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
- BZOJ 1483: [HNOI2009]梦幻布丁 [链表启发式合并]
1483: [HNOI2009]梦幻布丁 题意:一个带颜色序列,一种颜色合并到另一种,询问有多少颜色段 一种颜色开一个链表,每次遍历小的合并到大的里,顺带维护答案 等等,合并方向有规定? 令col[x ...
- bzoj 1483: [HNOI2009]梦幻布丁 启发式合并vector
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description N个 ...
- 1483: [HNOI2009]梦幻布丁
1483: [HNOI2009]梦幻布丁 链接 分析: 启发式合并+链表. 代码: #include<cstdio> #include<algorithm> #include& ...
- bzoj 1483: [HNOI2009]梦幻布丁
1483: [HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1 ...
- [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并)
[BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并) 题面 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1 ...
- bzoj 1483: [HNOI2009]梦幻布丁 (链表启发式合并)
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...
- BZOJ 1483 HNOI2009 梦幻布丁 名单+启示录式的合并
标题效果:特定n布丁.每个人都有一个颜色布丁,所有的布丁反复有一定的颜色变化的颜色,颜色反复询问的段数 数据范围:n<=10W 色彩数<=100W 启发式合并名单0.0 从来不写清楚 实际 ...
随机推荐
- SpringBoot数据库访问(一)--------关系型数据库访问(RDBMS)
关系型数据库访问(RDBMS) 采用JdbcTemplate.MyBatis.JPA.Hibernate等技术. 一.JdbcTemplate工具 在pom.xml添加boot-starter-jdb ...
- Java并发常见问题
ConcurrentHashMap源码分析,参考:http://blog.csdn.net/do_smile/article/details/46911727 HashMap源码分析,参考:http: ...
- Java注解(二)
前面了解了注解的基本内容,这次来看一下自定义注解. 自定义注解其实很简单,直接上代码: import java.lang.annotation.Documented; import java.lang ...
- Linux 添加定时任务,crontab -e 命令与直接编辑 /etc/crontab 文件
1. 使用 crontab -e 命令编辑定时任务列表 使用这个命令编辑的定时任务列表是属于用户级别的,初次编辑后在 /var/spool/cron 目录下生成一个与用户名相同的文件,文件内容就是我们 ...
- Java - HashMap值大于128问题
class Solution { public boolean wordPattern(String pattern, String str) { HashMap<Character,Integ ...
- local_listener参数的作用!
转自:http://warehouse.itpub.net/post/777/472788 pmon只会动态注册port等于1521的监听,否则pmon不能动态注册listener,要想让pmon动态 ...
- java ee思维导图
该图是以网上的脑图作为参考,结合教材具体内容完成.
- maven Could not find artifact com.** 无法下载原因分析
1.有时候经常莫名其妙的遇到这个问题:比如在idea重新导入一个新项目,或者在原来的空间里面引入一个新项目.去私服里面查看明明是有的,但是就是下载不下来. 结合网上搜的和自己遇到的,总结原因如下: 1 ...
- machine learning model(algorithm model) .vs. statistical model
https://www.analyticsvidhya.com/blog/2015/07/difference-machine-learning-statistical-modeling/ http: ...
- python函数修饰器(decorator)
python语言本身具有丰富的功能和表达语法,其中修饰器是一个非常有用的功能.在设计模式中,decorator能够在无需直接使用子类的方式来动态地修正一个函数,类或者类的方法的功能.当你希望在不修改函 ...