题目链接

https://loj.ac/problem/6032

题解

扫描线,先将每个操作按照y轴排序,考虑水从下面淹到上面。

对于挡板被截断的情况:并查集合并左侧和右侧的格子。

对于要求没有水的情况:如果水不淹到上面,那么它一定会被满足。

对于要求有水的情况:直接把下面的全淹了,再来更新答案。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>

const int maxn=100000;

int read()
{
  int x=0,f=1;
  char ch=getchar();
  while((ch<'0')||(ch>'9'))
    {
      if(ch=='-')
        {
          f=-f;
        }
      ch=getchar();
    }
  while((ch>='0')&&(ch<='9'))
    {
      x=x*10+ch-'0';
      ch=getchar();
    }
  return x*f;
}

struct data
{
  int op,x,y;

  data(int op_=0,int x_=0,int y_=0)
  {
    op=op_;
    x=x_;
    y=y_;
  }

  bool operator <(const data &other) const
  {
    if(y==other.y)
      {
        return op<other.op;
      }
    return y<other.y;
  }
};

namespace dsu
{
  int fa[maxn+10];

  inline int clear()
  {
    memset(fa,0,sizeof fa);
    return 0;
  }

  int find(int x)
  {
    return fa[x]?fa[x]=find(fa[x]):x;
  }
}

data d[maxn*2+10];
int f[maxn+10],ans[maxn+10],cnt,t,n,m,lastans;

int main()
{
  t=read();
  while(t--)
    {
      cnt=0;
      memset(f,0,sizeof f);
      memset(ans,0,sizeof f);
      lastans=0;
      dsu::clear();
      n=read();
      m=read();
      for(int i=1; i<n; ++i)
        {
          int h=read();
          d[++cnt]=data(-1,i,h);
        }
      while(m--)
        {
          int x=read(),y=read(),op=read();
          d[++cnt]=data(op,x,y);
        }
      std::sort(d+1,d+cnt+1);
      for(int i=1; i<=cnt; ++i)
        {
          if(d[i].op==-1)
            {
              int x=dsu::find(d[i].x),y=dsu::find(d[i].x+1);
              dsu::fa[y]=x;
              f[x]+=f[y];
              ans[x]+=ans[y];
              lastans=std::max(lastans,ans[x]);
            }
          else if(d[i].op==0)
            {
              lastans=std::max(lastans,++ans[dsu::find(d[i].x)]);
            }
          else
            {
              int x=dsu::find(d[i].x);
              lastans=std::max(lastans,ans[x]=std::max(ans[x],++f[x]));
            }
        }
      printf("%d\n",lastans);
    }
  return 0;
}