zoukankan      html  css  js  c++  java
  • 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);
    }
    
  • 相关阅读:
    volatile
    public && protected && private
    class && struct
    jQuery-实现全选与反选
    .NET Fframework
    C# 中的单精度与双精度区别
    C#中的集合(HashTable与Array类)
    c#中的数组、ArrayList、List区别
    C#属性和字段区别、get与set用法
    C#中委托和事件
  • 原文地址:https://www.cnblogs.com/nervendnig/p/11437711.html
Copyright © 2011-2022 走看看