【CERC2015】【BZOJ4432】Greenhouse Growth
2016-04-18 11:31
381 查看
Description
你从计算机科学转向农业,你的新工作包括在一个地下温室种植向日葵。在温室中有n个排列在一条直线的向日葵植株,从左向右编号为1到n。有A、B2个照射器为向日葵的生长提供光和热,且照射器A、B分别放置在向日葵的左右两端。
每天只有1个照射器被打开,使所有向日葵转向光源,并使部分向日葵生长。向日葵会生长当且仅当其朝向的相邻植株比它更高,其每天的生长高度为1厘米。请注意,一个植株的生长将使其背后的植株立刻开始生长。
样例数据前三天的生长情况
你将被给出向日葵的初始高度和接下来m天的光照计划,请计算所有向日葵最终的高度。
Input
第一行有2个整n和m(1<= n, m <=300 000)——植株数和天数。
接下来一行包括n个整数h1, h2,… , hn (1 <= hk <=109)——从左到右向日葵的初始高度。
接下来一行包括一个仅含字母A/B长度为m的字符串——从第一天开始的光照计划。
Output
n个整数——从左到右每株向日葵最终的高度
Sample Input
6 5
4 3 5 3 6 6
BABAA
Sample Output
5 5 6 6 6 6
HINT
Source
一开始觉得是线段树,实际上链表模拟一下就行了..
搞标记记录一下A亮的时候长不长,B亮的时候长不长,一个位置长不长,长多少都是可以用当前时间和之前时间来计算的
1表示A亮时候长,2表示B亮时候长,3表示两种都长
你从计算机科学转向农业,你的新工作包括在一个地下温室种植向日葵。在温室中有n个排列在一条直线的向日葵植株,从左向右编号为1到n。有A、B2个照射器为向日葵的生长提供光和热,且照射器A、B分别放置在向日葵的左右两端。
每天只有1个照射器被打开,使所有向日葵转向光源,并使部分向日葵生长。向日葵会生长当且仅当其朝向的相邻植株比它更高,其每天的生长高度为1厘米。请注意,一个植株的生长将使其背后的植株立刻开始生长。
样例数据前三天的生长情况
你将被给出向日葵的初始高度和接下来m天的光照计划,请计算所有向日葵最终的高度。
Input
第一行有2个整n和m(1<= n, m <=300 000)——植株数和天数。
接下来一行包括n个整数h1, h2,… , hn (1 <= hk <=109)——从左到右向日葵的初始高度。
接下来一行包括一个仅含字母A/B长度为m的字符串——从第一天开始的光照计划。
Output
n个整数——从左到右每株向日葵最终的高度
Sample Input
6 5
4 3 5 3 6 6
BABAA
Sample Output
5 5 6 6 6 6
HINT
Source
一开始觉得是线段树,实际上链表模拟一下就行了..
搞标记记录一下A亮的时候长不长,B亮的时候长不长,一个位置长不长,长多少都是可以用当前时间和之前时间来计算的
1表示A亮时候长,2表示B亮时候长,3表示两种都长
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #define MAXN 300010 #define GET (ch>='0'&&ch<='9') #define Abs(x) (x>=0?x:-x) using namespace std; inline void in(int &x) { char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar(); } int Tim,n,m,top,tp; int cnt[MAXN][4]; struct edge; struct seg; vector<edge*> now[MAXN][4]; struct edge { seg *pre,*nxt; inline void solve(); inline void merge(); }List[MAXN<<1]; struct seg { int l,r,flag,h0,t0; edge *pre,*nxt; inline int calc() { return h0+cnt[Tim][flag]-cnt[t0][flag]; } inline bool checka() { return pre&&pre->pre->calc()>calc(); } inline bool checkb() { return nxt&&nxt->nxt->calc()>calc(); } inline void update() { flag=checka()|(checkb()<<1); } }*first,*last,list[MAXN<<1]; inline void edge::solve() { int delta=abs(pre->calc()-nxt->calc()),flag=pre->flag^nxt->flag; if (delta&&flag&&cnt[Tim][flag]+delta<=300000) now[cnt[Tim][flag]+delta][flag].push_back(this); } inline void edge::merge() { if (!(pre&&nxt)) return; int h=pre->calc(); if (nxt->calc()!=h) return; seg* ret=pre; ret->l=pre->l;ret->r=nxt->r;ret->h0=h;ret->t0=Tim; ret->pre=pre->pre;ret->nxt=nxt->nxt;ret->update(); if (ret->pre) ret->pre->nxt=ret; if (ret->nxt) ret->nxt->pre=ret; if (ret->pre) ret->pre->solve(); if (ret->nxt) ret->nxt->solve(); pre=NULL;nxt=NULL; } int main() { in(n);in(m);int h;char ch=' '; for (int i=1;i<=n;i++) { in(h); if (last&&last->h0==h) { last->r=i;continue; } ++top;list[top].l=i;list[top].r=i;list[top].h0=h;list[top].t0=0; if (last) ++tp,List[tp].pre=last,List[tp].nxt=&list[top], last->nxt=&List[tp],list[top].pre=&List[tp],last->update(); else first=&list[top]; last=&list[top]; } last->update(); for (seg *i=first;i->nxt;i=i->nxt->nxt) i->nxt->solve(); while (ch!='A'&&ch!='B') ch=getchar(); for (Tim=1;Tim<=m;Tim++) { cnt[Tim][1]=cnt[Tim-1][1]+(ch=='A');cnt[Tim][2]=cnt[Tim-1][2]+(ch=='B'); cnt[Tim][3]=cnt[Tim-1][3]+1; for (int f=1;f<=3;f++) { int it=now[cnt[Tim][f]][f].size(); for (int i=0;i<it;i++) now[cnt[Tim][f]][f][i]->merge(); } if (Tim==m) { for (seg* i=first;i;i=i->nxt?i->nxt->nxt:NULL) for (int j=i->l;j<=i->r;++j) { if (j>1) putchar(' '); printf("%d",i->calc()); } putchar('\n'); } ch=getchar(); } }
相关文章推荐
- [C/C++]反转链表
- C#实现基于链表的内存记事本实例
- Transformation 能将 Windows XP/Server 2003 操作系统,完美地模拟成 Windows Vista 的软件
- 用javascript和css模拟select的脚本
- C语言实现带头结点的链表的创建、查找、插入、删除操作
- C++利用静态成员或类模板构建链表的方法讲解
- C++实现简单的学生管理系统
- PHP模拟asp.net的StringBuilder类实现方法
- C#使用ImitateLogin模拟登录百度
- javascript用层模拟可移动的小窗口
- JS模拟简易滚动条效果代码(附demo源码)
- 自编jQuery插件实现模拟alert和confirm
- Linux内核链表实现过程
- C++链表倒序实现方法
- JS模拟按钮点击功能的方法
- C#通过链表实现队列的方法
- PHP模拟asp中response类实现方法
- 模拟Spring的简单实现
- C#实现的简单链表类实例
- 找出链表倒数第n个节点元素的二个方法