对于高度相同的一段可以合并,用链表从左往右维护这些连续段,每段维护以下信息:

$l,r$:表示区间的左右端点。

$t,a$:表示在第$t$天结束时它的高度是$a$。

$b$:当阳光在左边时它是否会长高。

$c$:当阳光在右边时它是否会长高。

令$sa[i],sb[i]$分别表示前$i$天中阳光在左/右边的天数,那么显然第$i$天这一段的高度为$a+b(sa[i]-sa[t])+c(sb[i]-sb[t])$。

对于相邻的两段,根据其$b$和$c$,可以得出它们合并的时间。

一天一天进行模拟,每天只处理那一天可能发生的合并事件,然后重新计算新的合并发生的时间即可。

时间复杂度$O(n+m)$。

#include<cstdio>
const int N=300010,M=N*3;
int n,m,ca,cb,i,j,k,T,h[N],tot;char b[N];
int sa[N],sb[N],ga[N],gb[N],gab[N],v[M],nxt[M],ed;
struct P{int l,r,pre,nxt,t,a;bool b,c,del;}e[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int&x,int y){v[++ed]=y;nxt[ed]=x;x=ed;}
inline int ask(const P&p){return p.a+p.b*(ca-sa[p.t])+p.c*(cb-sb[p.t]);}
inline void cal(P&p){p.b=ask(p)<ask(e[p.pre]);p.c=ask(p)<ask(e[p.nxt]);
}
inline void merge(int o);
inline void check(int o){P&p=e[o],&q=e[p.nxt];int x=ask(p),y=ask(q),z=x<y?y-x:x-y;if(!z)merge(o);bool fa=(x>y)^p.b,fb=(x<y)^q.c;if(fa&&fb){if(ca+cb+z<=m)add(gab[ca+cb+z],o);return;}if(fa){if(ca+z<=m)add(ga[ca+z],o);return;}if(fb){if(cb+z<=m)add(gb[cb+z],o);return;}
}
inline void merge(int o){P&p=e[o];if(p.del||!p.nxt)return;P&q=e[p.nxt];int x=ask(p),y=ask(q);if(x!=y)return;q.del=1;p.r=q.r;p.nxt=q.nxt;if(q.nxt)e[q.nxt].pre=o;p.t=T,p.a=x;cal(p);if(p.pre)check(p.pre);if(p.nxt)check(o);
}
int main(){read(n),read(m);for(i=1;i<=n;i++)read(h[i]);for(i=1;i<=n;i=j){for(j=i;j<=n&&h[i]==h[j];j++);tot++;e[tot].l=i,e[tot].r=j-1;e[tot].a=h[i];}for(i=1;i<tot;i++)e[i].nxt=i+1;for(i=2;i<=tot;i++)e[i].pre=i-1;for(i=1;i<=tot;i++)cal(e[i]);for(i=1;i<tot;i++)check(i);scanf("%s",b+1);for(T=1;T<=m;T++){b[T]=='A'?ca++:cb++;sa[T]=sa[T-1]+(b[T]=='A');sb[T]=sb[T-1]+(b[T]=='B');for(j=ga[ca];j;j=nxt[j])merge(v[j]);for(j=gb[cb];j;j=nxt[j])merge(v[j]);for(j=gab[T];j;j=nxt[j])merge(v[j]);ga[ca]=gb[cb]=0;}for(i=1;i<=tot;i++)if(!e[i].del)for(k=ask(e[i]),j=e[i].l;j<=e[i].r;j++)h[j]=k;for(i=1;i<=n;i++)printf("%d%c",h[i],i<n?' ':'\n');return 0;
}

  

转载于:https://www.cnblogs.com/clrs97/p/6545482.html

BZOJ4432 : [Cerc2015]Greenhouse Growth相关推荐

  1. 汽车高级驾驶辅助系统ADAS激光雷达创新者Cepton与Growth Capital达成企业合并协议

    汽车高级驾驶辅助系统 (ADAS) 和车辆自动驾驶领域光感测距技术(激光雷达)的创新者Cepton Technologies, Inc.(以下简称"Cepton")将与Growth ...

  2. 程序猿崛起——Growth Hacker

    新生事物总是充满了生命力,你不需要去关注,它也会不断的跳入你的眼帘.最近常常看到的一个词汇叫做Growth Hacker,这个词汇如此之新,以至于还没有对应的中文翻译,直接翻译为成长黑客似乎也不妥帖. ...

  3. Growth Hacking背后,数据分析平台的架构调整

    Growth Hacking背后,数据分析平台的架构调整 发表于2015-11-03 11:05| 1547次阅读| 来源CSDN| 6 条评论| 作者蒲婧 CTO俱乐部CTOCTO讲堂Growth ...

  4. 【Effect CodeForces - 270D】Greenhouse (思维,最长非递减子序列(上升),对偶问题,考虑反面)

    题干: Emuskald is an avid horticulturist and owns the world's longest greenhouse - it is effectively i ...

  5. Frequent Pattern 挖掘之二(FP Growth算法)(转)

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...

  6. 云上的Growth hacking之路,打造产品的增长引擎

    增长关乎产品的存亡 增长!增长!增长!业务增长是每一个创业者每天面临的最大问题.无论你的产品是APP,还是web,或者是小程序,只能不断的维持用户的增长,才能向资本市场讲出一个好故事,融资活下去.活到 ...

  7. BZOJ 4421: [Cerc2015] Digit Division 排列组合

    4421: [Cerc2015] Digit Division 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4421 Descripti ...

  8. Bzoj 4422: [Cerc2015]Cow Confinement(线段树+扫描线)

    以下内容来自ShallWe's Blog 题目 题目链接 4422: [Cerc2015]Cow Confinement Description 一个10^6行10^6列的网格图,上面有一些牛.花和一 ...

  9. 频繁模式增长Frequent-Pattern Growth(FP-Growth)

    文章目录 频繁模式增长Frequent-Pattern Growth(FP-Growth) 从DB构建一个FP树 挖掘FP树 FP-Growth构建 频繁模式增长Frequent-Pattern Gr ...

最新文章

  1. Linux10-归档、系统间复制文件
  2. mvc 下的 signalR使用小结
  3. gateway java_基于SpringCloudGateway 实现的网关
  4. Xshell连接不上Linux的解决方法
  5. vue设置全局变量或函数
  6. 2017(深圳) .NET技术分享交流会 第二期,将有网络直播
  7. GIS实战应用案例100篇(二)-元胞自动机模拟城市扩张过程
  8. 你会用Java实现两个大数相加吗
  9. java jndi使用_Java项目中使用JNDI连接数据库
  10. java需求设计_JavaWeb期末设计---需求分析文档. stage1
  11. android中svn插件安装,AndroidSDK安装SVN插件问题解决
  12. Qt笔记-桌面应用程序加载字体库(ttf)
  13. python压缩文件操作_python处理zip压缩文件 | 学步园
  14. Linux防火墙Firewall和Iptables的使用
  15. 通过深度优先搜索(DFS)对图的边进行分类
  16. 加一度分享:如何降低推广预算,增加KPI
  17. Linux查看磁盘空间和文件夹大小
  18. Rust : AES算法加密、解密
  19. HDMI转PGA电脑没有声音处理方法
  20. ptp精准时间协议_精确时间协议PTP研究

热门文章

  1. (char*)malloc(sizeof(char))有什么用,为什么要这么写——简单介绍指针
  2. Java获得随机数字
  3. 从SOURCE_BUFFER单元开始存放了20个字母A, 编程将这20个字母A的字符串传送到DEST_BUFFER开始的单元中.
  4. C语言文件操作基本常识
  5. OpenGL生成的法线贴图并增加光照
  6. 【细说软件工程】《软件工程》Software Engineering
  7. 手写简版spring --1--创建简单的Bean容器
  8. 查看docker的端口映射情况
  9. Java8新特性之函数式接口
  10. 详解网络摄像机中的IR-CUT