记录编号 481402 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2015]品酒大会 最终得分 100
用户昵称 GravatarCooook 是否通过 通过
代码语言 C++ 运行时间 2.292 s
提交时间 2018-01-02 18:53:20 内存使用 99.31 MiB
显示代码纯文本
# include <bits/stdc++.h>
typedef long long ll;
const int MAXN = 600005;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
int n, cnt, trans[MAXN][26], fa[MAXN], Mx[MAXN], last, val[MAXN], first[MAXN], e = 1;
char s[MAXN]; ll size[MAXN], mx[MAXN], mn[MAXN], Ans1[MAXN], Ans2[MAXN];


inline int read() {
    int x = 0, f = 1; char ch = getchar();
    for (; ch < '0' | ch > '9'; ch = getchar()) ch == '-'? f = -f:0;
    for (; ch <= '9' & ch >= '0'; ch = getchar()) x = x * 10 + (ch ^ 48);
    return x * f;
}

struct edge{
    int u,v,next;
}a[MAXN];

inline void push(int u,int v) {
    a[e].u = u; a[e].v = v; a[e].next = first[u]; first[u] = e++;
}

inline void Add(int c) {
    int np = ++ cnt, p = last; Mx[np] = Mx[p] + 1; ++ size[np]; 
    for (; p && !trans[p][c]; p = fa[p]) trans[p][c] = np;
    if (!p) fa[np] = 1;
    else {
        int q = trans[p][c];
        if (Mx[q] == Mx[p] + 1) fa[np] = q;
        else {
            int nq = ++ cnt; Mx[nq] = Mx[p] + 1;
            fa[nq] = fa[q]; fa[np] = fa[q] = nq;
            memcpy(trans[nq], trans[q], sizeof trans[q]);
            for (; trans[p][c] == q; p = fa[p]) trans[p][c] = nq;
        } 
    } last = np;
}

inline void gmax(ll &a, ll b) {if (a < b) a = b;}
inline void gmin(ll &a, ll b) {if (a > b) a = b;}

inline void dp(int u) {
    if (!size[u]) mx[u] = -inf, mn[u] = inf;
    for (int i = first[u]; i; i = a[i].next) {
        dp(a[i].v);
        if (mx[u] != -inf && mx[a[i].v] != -inf && mn[u] != inf && mn[a[i].v] != inf) 
            gmax(Ans2[Mx[u]], std::max(mx[u] * mx[a[i].v], mn[u] * mn[a[i].v]));
        gmax(mx[u], mx[a[i].v]);
        gmin(mn[u], mn[a[i].v]);
        Ans1[Mx[u]] += size[u] * size[a[i].v];
        size[u] += size[a[i].v];
    }
}

int main() {
    freopen("savour.in","r",stdin);
    freopen("savour.out","w",stdout);
    std::fill(Ans2, Ans2 + MAXN, -inf);
    n = read();
    scanf("%s", s + 1); last = ++ cnt;
    for (int i = 1; i <= n; i++) val[i] = read();
    for (int i = n; i; --i) Add(s[i] - 'a'), mx[last] = mn[last] = val[i];
    for (int i = 2; i <= cnt; i++) push(fa[i], i); dp(1);
    for (int i = n - 1; ~i; i--) Ans1[i] += Ans1[i + 1], gmax(Ans2[i], Ans2[i + 1]);
    for (int i = 0; i < n; i++) 
        if (Ans1[i]) printf("%lld %lld\n", Ans1[i], Ans2[i]);
        else puts("0 0");
    getchar(); getchar();
    return 0;
}