[链表 杂题] BZOJ 4432 [Cerc2015]Greenhouse Growth

只有我觉得神题吗 比C难度还大?

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

看懂了也不会写 不会告诉你我是看着标程写的

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define pb push_back
using namespace std;

inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
  char c=nc(),b=1;
  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void read(char &x){
  for (x=nc();x!='A' && x!='B';x=nc());
}

const int N=300005;

struct node;

int n,m,T;
int cnt[N][4];
vector<node*> ev[N][4];

struct node{
  int lp,rp,h0,t0,g; // 1 A 2 B 3 BOTH
  node *l,*r;
  int del;

  bool GA(){ return l && l->l->H()>H();}
  bool GB(){ return r && r->r->H()>H();}
  void get(){ g=GA()|(GB()<<1);}
  int H(){ return h0+cnt[T][g]-cnt[t0][g];}

  void modify(){
    int dh=abs(l->H()-r->H()),sg=l->g^r->g;
    if (dh && sg){
      int c=cnt[T][sg]+dh;
      if (c<=m) ev[c][sg].pb(this);
    }
  }
  void wake(){
    if (del || l->H()!=r->H()) return;
    int h=l->H();
    node* ret=l; ret->r=r->r; if (ret->r) ret->r->l=ret;
    ret->lp=l->lp,ret->rp=r->rp,ret->h0=h,ret->t0=T;
    ret->get();
    if (ret->l) ret->l->modify();
    if (ret->r) ret->r->modify();
    del=1;
  }
}memory[N<<1];
int ncnt;

int main(){
  int h; char c;
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  read(n); read(m);

  node *head=NULL,*pre=NULL,*mid,*cur;
  for (int i=1;i<=n;i++){
    read(h);
    if (pre && h==pre->h0) { pre->rp=i; continue; }
    cur=memory+(++ncnt);
    cur->lp=i,cur->rp=i,cur->h0=h,cur->t0=0;
    if (pre){
      mid=memory+(++ncnt);
      mid->l=pre,mid->r=cur,pre->r=mid,cur->l=mid;
      pre->get();
    }else
      head=cur;
    pre=cur;
  }
  pre->get();

  for (node* p=head;p->r;p=p->r->r)
    p->r->modify();

  for (T=1;T<=m;++T){
    read(c);
    cnt[T][1]=cnt[T-1][1]+(c=='A'),cnt[T][2]=cnt[T-1][2]+(c=='B'),cnt[T][3]=cnt[T-1][3]+1;
    for (int g=1;g<=3;g++)
      for (int i=0;i<(int)ev[cnt[T][g]][g].size();i++)
    ev[cnt[T][g]][g][i]->wake();
  }

  T=m;
  for (node* p=head;p;p=p->r->r){
    for (int i=p->lp;i<=p->rp;i++)
      printf("%d%c",p->H(),i==n?'\n':' ');
    if (!(p->r)) break;
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值