# 【CERC2015】【BZOJ4432】Greenhouse Growth

Description

Input

Output

n个整数——从左到右每株向日葵最终的高度
Sample Input

6 5

4 3 5 3 6 6

BABAA

Sample Output

5 5 6 6 6 6
HINT

Source

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();
}
}