codeforces 873F 后缀数组+单调栈(fastio)

1.不能以某些位置结尾=不能以某些位置开头,于是倒转字符串

2.不考虑禁止的情况,则题目转化为height数组上求最大矩形,进行两次单调栈即可

3.考虑禁止的情况,实际上就等于计算次数的时候,减少合法区间内的1的个数

嗯,顺便存一下最终的fastio和后缀数组板子,以后应该不会再换了

#include<bits/stdc++.h>
#define ll long long
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
using namespace std;//head
const int maxn=4e5+10,maxm=2e6+10;
const ll INF=0x3f3f3f3f,mod=1e9+7;
int casn,n,m,k,num[maxn];
namespace fastio{//@精简版,支持读取整数,字符串,输出整数@
bool isdecimal(char c){return (c >= 48 && c <= 57) || (c == 46);}
bool isdigit(char c){return c >= 48 && c <= 57;}
const int maxsz=10000000;
class fast_iostream{public:
  bool endf = 1,flag;
  char ch = get_char();
  char get_char(){
    static char buffer[maxsz], *a = buffer, *b = buffer;
    return a == b && (b = (a = buffer) + fread(buffer, 1, maxsz, stdin), b == a) ? EOF : *a++;
  }
  template <typename type> bool get_signed(type& tmp){
    flag = 0;tmp = 0;
    while (!isdigit(ch) && ch != EOF){flag = ch == '-';ch = get_char();};
    if (ch == EOF) return endf = 0;
    do{tmp = tmp*10 + ch - 48;} while (isdigit(ch = get_char()));
    if (flag) tmp = -tmp;
    return 1;
  }
  template <typename type>bool get_unsigned(type& tmp){
    tmp = 0;
    while (!isdigit(ch) && ch != EOF) ch = get_char();
    if (ch == EOF) return endf = 0;
    do{tmp = tmp*10 + ch - 48;} while (isdigit(ch = get_char()));
    return 1;
  }
  int get_str(char* str){
    char* tmp = str;
    while (ch == '
' || ch == '
' || ch == ' ') ch = get_char();
    if (ch == EOF) return (endf = 0), *tmp = 0;
    do{*(tmp++) = ch;ch = get_char();} while (ch != '
' && ch != '
' && ch != ' ' && ch != EOF);
    *(tmp++) = '';
    return static_cast<int>(tmp - str - 1);
  }
  typedef char* charptr;
  fast_iostream& operator>>(char* tmp){get_str(tmp);return *this;}
  template <typename type>fast_iostream& operator>>(type& tmp){get_signed(tmp);return *this;}
  operator bool() const {return endf;}
};
template <typename type>void put(type tmp){
  if (tmp == 0){putchar(48);return;}
  static int top,stk[21];
  if (tmp < 0){tmp = -tmp;putchar('-');}
  while (tmp) stk[++top] = tmp % 10, tmp /= 10;
  while (top) putchar(stk[top--] + 48);
}
}fastio::fast_iostream io;
#define rank _rank
namespace suffix{
  int tr[maxn],rank[maxn],sa[maxn],h[maxn],has[maxn];
  int cmp(int x,int y,int k){
    if(x+k>n||y+k>n)return 0;
    return rank[x]==rank[y]&&rank[x+k]==rank[y+k];
  }
  void getsa(char *s,int n,int m=233){
    int i,cnt;
    for(i=1;i<=n;i++)has[s[i]]++;
    for(i=1,cnt=0;i<=m;i++)if(has[i])tr[i]=++cnt;
    for(i=1;i<=m;i++)has[i]+=has[i-1];
    for(i=1;i<=n;i++)rank[i]=tr[s[i]],sa[has[s[i]]--]=i;
    for(int k=1;cnt!=n;k<<=1){
      for(i=1;i<=n;i++)has[i]=0;
      for(i=1;i<=n;i++)has[rank[i]]++;
      for(i=1;i<=n;i++)has[i]+=has[i-1];
      for(i=n;i>=1;i--)if(sa[i]>k)tr[sa[i]-k]=has[rank[sa[i]-k]]--;
      for(i=1;i<=k;i++)tr[n-i+1]=has[rank[n-i+1]]--;
      for(i=1;i<=n;i++)sa[tr[i]]=i;
      for(i=1,cnt=0;i<=n;i++)tr[sa[i]]=cmp(sa[i],sa[i-1],k) ? cnt:++cnt;
      for(i=1;i<=n;i++)rank[i]=tr[i];
    }
    for(int i=1;i<=n;i++){
      if(rank[i]==1)continue;
      for(int j=max(1,h[rank[i-1]]-1);;j++){
        if(s[i+j-1]==s[sa[rank[i]-1]+j-1])h[rank[i]]=j;
        else break;
      }
    }
  }
}using namespace suffix;
char s1[maxn],s2[maxn];
int sum[maxn],l[maxn],r[maxn];
void getmn(int *a,int s,int t){
  stack<int> stk;
  while(!stk.empty()) stk.pop();
    rep(i,s,t){
      while(!stk.empty()&&a[stk.top()]>=a[i]) stk.pop();
      if(!stk.empty()) l[i]=stk.top()+1;
      else l[i]=s;
      stk.push(i);
    }
    while(!stk.empty()) stk.pop();
    per(i,s,t){
      while(!stk.empty()&&a[stk.top()]>=a[i]) stk.pop();
      if(!stk.empty()) r[i]=stk.top()-1;
      else r[i]=t;
      stk.push(i);
    }
}
int main(){
  io>>n;
  io>>(s1+1)>>(s2+1);
  reverse(s1+1,s1+1+n);
  reverse(s2+1,s2+1+n);
  getsa(s1,n,233);
  rep(i,1,n) sum[i]=sum[i-1]+(s2[sa[i]]=='1');
  ll ans=0;
  rep(i,1,n) if(s2[i]=='0')ans=max(ans,n-i+1ll);
  getmn(h,1,n);
  rep(i,2,n) {
    ll len=h[i],rg=(r[i]-l[i]+2-(sum[r[i]]-sum[max(0,l[i]-2)]));
    ans=max(ans,len*rg);
  }
  fastio::put(ans);
}
原文地址:https://www.cnblogs.com/nervendnig/p/11437711.html