当前位置: 首页 > news >正文

hdu 5997 rausen loves cakes(线段数合并+启发式修改)

题目链接:hdu 5997 rausen loves cakes

题意:

给你n个点,每个点有一个颜色,现在有两个操作,第一个操作,将颜色x改为颜色y,第二个操作,询问[x,y]区间有多少颜色段(颜色段的定义为从左往右相同的颜色为一段,遇到不相同的为下一段,ie:144112为4段颜色)

题解:

对于第二个操作我们可以写一个线段树合并来搞定,对于第一个操作,就要用启发式修改来进行,如何启发式?

我们开一个数组来记录每个颜色对应的颜色,最开始都是对应自己,然后开一个vector来记录每个颜色的位置,然后遇到将a颜色改为b颜色,就暴力修改位置数最小的那个,然后记录一下对应的颜色就行了,这样就能将修改操作的总复杂度降到log级别。

  1 #include<bits/stdc++.h>
  2 #define pb push_back
  3 #define ls l,m,rt<<1
  4 #define rs m+1,r,rt<<1|1
  5 #define F(i,a,b) for(int i=a;i<=b;++i)
  6 using namespace std;
  7 
  8 const int N=1e5+7;
  9 int col[N*10];
 10 vector<int>cnt[N*10];
 11 int t,n,q;
 12 struct node{int l,r,val;}tr[N*4];
 13 
 14 void up(int rt)
 15 {
 16     tr[rt].l=tr[rt<<1].l;
 17     tr[rt].r=tr[rt<<1|1].r;
 18     tr[rt].val=tr[rt<<1].val+tr[rt<<1|1].val;
 19     if(tr[rt<<1].r==tr[rt<<1|1].l)tr[rt].val--;
 20 }
 21 
 22 void build(int l=1,int r=n,int rt=1)
 23 {
 24     if(l==r)
 25     {
 26         scanf("%d",&tr[rt].l);
 27         tr[rt].r=tr[rt].l,tr[rt].val=1;
 28         cnt[tr[rt].l].pb(l);
 29         return;
 30     }
 31     int m=l+r>>1;
 32     build(ls),build(rs);
 33     up(rt);
 34 }
 35 
 36 void update(int pos,int b,int l=1,int r=n,int rt=1)
 37 {
 38     if(l==r)
 39     {
 40         tr[rt].r=tr[rt].l=b,tr[rt].val=1;
 41         return;
 42     }
 43     int m=l+r>>1;
 44     if(pos<=m)update(pos,b,ls);
 45     else update(pos,b,rs);
 46     up(rt);
 47 }
 48 
 49 node query(int x,int y,int l=1,int r=n,int rt=1)
 50 {
 51     if(l==r)return tr[rt];
 52     if(x<=l&&r<=y)return tr[rt];
 53     int m=l+r>>1;
 54     node ll,rr,ans;
 55     if(y<=m)ans=query(x,y,ls);
 56     else if(x>m)ans=query(x,y,rs);
 57     else
 58     {
 59         ll=query(x,y,ls);
 60         rr=query(x,y,rs);
 61         ans.l=ll.l,ans.r=rr.r;
 62         if(ll.r!=rr.l)ans.val=ll.val+rr.val;
 63         else ans.val=ll.val+rr.val-1;
 64     }
 65     return ans;
 66 }
 67 
 68 int main(){
 69     scanf("%d",&t);
 70     while(t--)
 71     {
 72         F(i,1,1000000)cnt[i].clear(),col[i]=i;
 73         scanf("%d%d",&n,&q);
 74         build();
 75         F(i,1,q)
 76         {
 77             int a,b,c;
 78             scanf("%d%d%d",&a,&b,&c);
 79             if(a==1)
 80             {
 81                 int x=col[b],y=col[c];
 82                 if(x==y)continue;
 83                 if(cnt[x].size()<cnt[y].size())
 84                 {
 85                     int en=cnt[x].size()-1;
 86                     F(j,0,en)
 87                     {
 88                         update(cnt[x][j],y);
 89                         cnt[y].pb(cnt[x][j]);
 90                     }
 91                     cnt[x].clear();
 92                 }else
 93                 {
 94                     col[b]=y,col[c]=x;
 95                     int en=cnt[y].size()-1;
 96                     F(j,0,en)
 97                     {
 98                         update(cnt[y][j],x);
 99                         cnt[x].pb(cnt[y][j]);
100                     }
101                     cnt[y].clear();
102                 }
103             }else printf("%d\n",query(b,c).val);
104         }
105     }
106     return 0;
107 }
View Code

 

转载于:https://www.cnblogs.com/bin-gege/p/6194312.html

相关文章:

  • 算法导论学习笔记——散列表
  • 百度网盘生成二维码api
  • 算法导论学习笔记——二叉查找树
  • win10安装blueCFD
  • 算法导论学习笔记——红黑树
  • 理解Linux文件系统
  • 沙盒SandBox
  • Python数据类型间互转(字典、字符串、列表、元组)
  • 输入n个整数,输出其中最小的k个
  • cocos2dx 3.x 精灵重叠时点击最上层的精灵
  • 输入一个整型数组,求所有子数组中和的最大值
  • 软件测试知识之分类
  • 算法导论学习笔记——贪心算法
  • web前端开发浏览器兼容性处理大全
  • 算法导论学习笔记——动态规划
  • 时间复杂度分析经典问题——最大子序列和
  • Angular 4.x 动态创建组件
  • Hibernate最全面试题
  • HTML-表单
  • IndexedDB
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Java超时控制的实现
  • Python实现BT种子转化为磁力链接【实战】
  • Python学习笔记 字符串拼接
  • Redash本地开发环境搭建
  • socket.io+express实现聊天室的思考(三)
  • unity如何实现一个固定宽度的orthagraphic相机
  • 诡异!React stopPropagation失灵
  • 技术发展面试
  • 思维导图—你不知道的JavaScript中卷
  • 我这样减少了26.5M Java内存!
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​iOS实时查看App运行日志
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • (07)Hive——窗口函数详解
  • (11)MATLAB PCA+SVM 人脸识别
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (二)PySpark3:SparkSQL编程
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (六)软件测试分工
  • (论文阅读30/100)Convolutional Pose Machines
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (四)c52学习之旅-流水LED灯
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)德国人的记事本
  • .NET 常见的偏门问题
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET基础篇——反射的奥妙
  • .sh