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

$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)$。

  1. #include<cstdio>
  2. const int N=300010,M=N*3;
  3. int n,m,ca,cb,i,j,k,T,h[N],tot;char b[N];
  4. int sa[N],sb[N],ga[N],gb[N],gab[N],v[M],nxt[M],ed;
  5. struct P{int l,r,pre,nxt,t,a;bool b,c,del;}e[N];
  6. 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';}
  7. inline void add(int&x,int y){v[++ed]=y;nxt[ed]=x;x=ed;}
  8. inline int ask(const P&p){return p.a+p.b*(ca-sa[p.t])+p.c*(cb-sb[p.t]);}
  9. inline void cal(P&p){
  10. p.b=ask(p)<ask(e[p.pre]);
  11. p.c=ask(p)<ask(e[p.nxt]);
  12. }
  13. inline void merge(int o);
  14. inline void check(int o){
  15. P&p=e[o],&q=e[p.nxt];
  16. int x=ask(p),y=ask(q),z=x<y?y-x:x-y;
  17. if(!z)merge(o);
  18. bool fa=(x>y)^p.b,fb=(x<y)^q.c;
  19. if(fa&&fb){
  20. if(ca+cb+z<=m)add(gab[ca+cb+z],o);
  21. return;
  22. }
  23. if(fa){
  24. if(ca+z<=m)add(ga[ca+z],o);
  25. return;
  26. }
  27. if(fb){
  28. if(cb+z<=m)add(gb[cb+z],o);
  29. return;
  30. }
  31. }
  32. inline void merge(int o){
  33. P&p=e[o];
  34. if(p.del||!p.nxt)return;
  35. P&q=e[p.nxt];
  36. int x=ask(p),y=ask(q);
  37. if(x!=y)return;
  38. q.del=1;
  39. p.r=q.r;
  40. p.nxt=q.nxt;
  41. if(q.nxt)e[q.nxt].pre=o;
  42. p.t=T,p.a=x;
  43. cal(p);
  44. if(p.pre)check(p.pre);
  45. if(p.nxt)check(o);
  46. }
  47. int main(){
  48. read(n),read(m);
  49. for(i=1;i<=n;i++)read(h[i]);
  50. for(i=1;i<=n;i=j){
  51. for(j=i;j<=n&&h[i]==h[j];j++);
  52. tot++;
  53. e[tot].l=i,e[tot].r=j-1;
  54. e[tot].a=h[i];
  55. }
  56. for(i=1;i<tot;i++)e[i].nxt=i+1;
  57. for(i=2;i<=tot;i++)e[i].pre=i-1;
  58. for(i=1;i<=tot;i++)cal(e[i]);
  59. for(i=1;i<tot;i++)check(i);
  60. scanf("%s",b+1);
  61. for(T=1;T<=m;T++){
  62. b[T]=='A'?ca++:cb++;
  63. sa[T]=sa[T-1]+(b[T]=='A');
  64. sb[T]=sb[T-1]+(b[T]=='B');
  65. for(j=ga[ca];j;j=nxt[j])merge(v[j]);
  66. for(j=gb[cb];j;j=nxt[j])merge(v[j]);
  67. for(j=gab[T];j;j=nxt[j])merge(v[j]);
  68. ga[ca]=gb[cb]=0;
  69. }
  70. 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;
  71. for(i=1;i<=n;i++)printf("%d%c",h[i],i<n?' ':'\n');
  72. return 0;
  73. }

  

BZOJ4432 : [Cerc2015]Greenhouse Growth的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. 表空间统计报告 Tablespace growth Report

    SQL> select TS# from v$tablespace where name='ABC' ; TS# ---------- 6 set serverout on set verify ...

  3. FP - growth 发现频繁项集

    FP - growth是一种比Apriori更高效的发现频繁项集的方法.FP是frequent pattern的简称,即常在一块儿出现的元素项的集合的模型.通过将数据集存储在一个特定的FP树上,然后发 ...

  4. [BZOJ 4436][Cerc2015]Kernel Knights

    [Cerc2015]Kernel Knights Time Limit: 2 Sec Memory Limit: 512 MBSubmit: 5 Solved: 4[Submit][Status][D ...

  5. How to control PrincipalObjectAccess table growth in Microsoft Dynamics CRM 2011

    https://support.microsoft.com/en-us/kb/2664150 How to control PrincipalObjectAccess table growth in ...

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

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

  7. Error Domain=com.google.greenhouse Code=-102

    *** Terminating app due to uncaught exception 'com.google.greenhouse', reason: 'Error Domain=com.goo ...

  8. FP—Growth算法

    FP_growth算法是韩家炜老师在2000年提出的关联分析算法,该算法和Apriori算法最大的不同有两点: 第一,不产生候选集,第二,只需要两次遍历数据库,大大提高了效率,用31646条测试记录, ...

  9. 关联规则算法之FP growth算法

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

随机推荐

  1. labelme连续将文件夹中的json文件进行可视化的指令

    for /r C:\Users\Fourmi\Desktop\ZP0 %i in (*.json) do labelme_json_to_dataset %i

  2. BZoj 2301 Problem b(容斥定理+莫比乌斯反演)

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 7732  Solved: 3750 [Submi ...

  3. (4).NET CORE微服务 Micro-Service ---- Consul服务发现和消费

    上一章说了  Consul服务注册  现在我要连接上Consul里面的服务 请求它们的API接口 应该怎么做呢? 1.找Consul要一台你需要的服务器 1.1 获取Consul下的所有注册的服务 u ...

  4. csv导入数据到mongodb3.2

    mongoimport.exe -d paper -c paper K:\paper.csv --type csv -f id,name 数据库名 表名      文件所在位置      文件类型   ...

  5. RequireJS跨域加载html模版后被转成JS问题分析及解决

    问题描述 RequireJS跨域加载HTML模版失败,例如: 在a.com域名下请求CDN域名下的模版,text.js插件会把html文件转成html.js文件去加载,由于并没有生成html.js文件 ...

  6. 如何查找物理cpu,cpu核心和逻辑cpu的数量

    环境 Red Hat Enterprise Linux 4 Red Hat Enterprise Linux 5 Red Hat Enterprise Linux 6 Red Hat Enterpri ...

  7. POJ2676 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解.SPJ 题解 DLX + 矩阵构建  (两个传送门) 代码 #includ ...

  8. youDao

    2018-09-22Journeys end in lovers' meeting.漂泊止于爱人的相遇. All extremes of feeling are allied with madness ...

  9. sql查询一个字段不同值并返回

    sql SELECT COUNT(字段),分组字段,SUM(字段),SUM(字段) FROM 表 GROUP BY 分组字段 java EntityWrapper<ProjectEntity&g ...

  10. sql查询count 单独字段不同值

    1.单表查询 SELECT COUNT(CASE WHEN (字段=值列1) THEN reportstatus END) AS 已上报,COUNT(CASE WHEN (字段=值列0) THEN 字 ...