zoukankan      html  css  js  c++  java
  • BZOJ 4199: [Noi2015]品酒大会 后缀自动机+逆序更新

    一道裸题,可以考虑自底向上去更新方案数与最大值。

    没啥难的

    细节........

    Code:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 
    #define maxn 1000006
    #define inf -0x3f3f3f3f3f3f3f3fll 
    #define ll long long 
    using namespace std;
    int n,is[maxn],appear[maxn];  
    long long val[maxn],ans1[maxn],ans2[maxn],maxv[maxn],minv[maxn]; 
    char str[maxn]; 
    // struct Graph{
    //     int head[maxn],to[maxn],nex[maxn],edges;
    //     void addedge(int u,int v) { nex[++edges] = head[u],head[u] = edges,to[edges] = v; }
    // }G; 
    struct SAM{
        int f[maxn],cnt[maxn],ch[maxn][30],len[maxn],tot,last; 
        int C[maxn],rk[maxn]; 
        void init() { 
            tot = last = 1; 
            for(int i = 0;i < maxn; ++i) ans2[i] = inf; 
        }
        void ins(int c,int cur){
            int np = ++tot,p = last; len[np] = len[last] + 1, last = tot; 
            while(p && !ch[p][c]) ch[p][c] = np,p = f[p];
            if(!p) f[np] = 1;
            else{
                int q = ch[p][c]; 
                if(len[q] == len[p] + 1) f[np] = q;
                else {
                    int nq = ++tot;
                    len[nq] = len[p] + 1; 
                    is[nq] = 1; 
                    memcpy(ch[nq],ch[q],sizeof(ch[q])); 
                    f[nq] = f[q],f[q] = f[np] = nq;
                    while(p && ch[p][c] == q) ch[p][c] = nq,p = f[p];
                }
            }
            ++cnt[last];
            maxv[last] = val[cur];
            minv[last] = val[cur];
        }
        void build(){
            for(int i = 1;i <= tot; ++i) ++C[len[i]];
            for(int i = 1;i <= tot; ++i) C[i] += C[i - 1];
            for(int i = 1;i <= tot; ++i) rk[C[len[i]]--] = i; 
            for(int i = tot;i >= 1; --i) {
                int p = rk[i];
                ans1[len[f[p]]] += (long long)cnt[f[p]] * cnt[p];
                cnt[f[p]] += cnt[p];  
                if(is[f[p]] && !appear[f[p]]) 
                {
                    appear[f[p]] = 1;
                    minv[f[p]] = minv[p];
                    maxv[f[p]] = maxv[p];
                    continue;   
                }
                ans2[len[f[p]]] = max(ans2[len[f[p]]],maxv[p]*maxv[f[p]]); 
                ans2[len[f[p]]] = max(ans2[len[f[p]]],minv[p]*minv[f[p]]); 
                maxv[f[p]] = max(maxv[f[p]],maxv[p]); 
                minv[f[p]] = min(minv[f[p]],minv[p]); 
            }
        }
    }sam; 
    int main(){
        // setIO("input"); 
        scanf("%d",&n),scanf("%s",str),sam.init(); 
        for(int i = 0;i < n; ++i) scanf("%lld",&val[i]); 
        for(int i = n - 1;i >= 0; --i) sam.ins(str[i] - 'a',i);
        sam.build(); 
        for(int i = n - 1;i >= 0; --i) {
            ans1[i] += ans1[i + 1];
            ans2[i] = max(ans2[i],ans2[i+1]); 
        }
        for(int i = 0;i < n; ++i) {
            if(!ans1[i]) printf("%d %d
    ",0,0);
            else printf("%lld %lld
    ",ans1[i],ans2[i]); 
        }
        return 0; 
    }
    

      

  • 相关阅读:
    Spring学习(一)初识Spring
    搜索引擎学习(七)解析查询
    搜索引擎学习(六)Query的子类查询
    Oracle学习(十四)分表分区
    Oracle学习(十三)优化专题
    Python学习————流程控制之while循环
    Python学习————深浅copy
    Python学习————while循环作业
    Python学习————运算符
    Python学习————与用户交互
  • 原文地址:https://www.cnblogs.com/guangheli/p/10361757.html
Copyright © 2011-2022 走看看