您的位置:首页 > 其它

【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表示两种都长

#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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模拟 链表