• noi2015品酒大会(sa)


    用常用的套路,排序之后从大到小插入height,用并查集维护即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=300010;
    const ll inf=1e18;
    int n,sa[maxn],H[maxn],ra[maxn],tong[maxn],m,tp[maxn],fa[maxn];
    ll ans1[maxn],ans2[maxn],c[maxn];
    char s[maxn]; 
    int getfa(int x){return (x==fa[x])?x:fa[x]=getfa(fa[x]);}
    void rsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[ra[tp[i]]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[ra[tp[i]]]--]=tp[i];
    }
    int cmp(int x,int y,int w){return tp[x]==tp[y]&&tp[x+w]==tp[y+w];}
    void pre(){
        for(int i=1;i<=n;++i)ra[i]=s[i]-'a'+1,tp[i]=i;
        
        m=32;rsort();
        
        for(int w=1,p=1,i;p<n;w+=w,m=p){
            for(p=0,i=n-w+1;i<=n;++i)tp[++p]=i;
            for(i=1;i<=n;++i)if(sa[i]>w)tp[++p]=sa[i]-w;
            rsort();swap(tp,ra);ra[sa[1]]=p=1;
            for(i=2;i<=n;++i)ra[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
        }
        int j,k=0;
        for(int i=1;i<=n;H[ra[i++]]=k)
            for(k=k?k-1:k,j=sa[ra[i]-1];s[i+k]==s[j+k];++k);
    }
    struct node{
        int id,v;
        bool operator<(const node&t)const{
            return v<t.v;
        }
    }tmp[maxn];
    struct lian{
        int l,r;
        ll ma,mi,len;
    }a[maxn];
    void merge(int x,int y,int w){
        x=getfa(x);y=getfa(y);
        ll t1=max(a[x].ma*a[y].ma,a[x].mi*a[y].mi);
        ll t2=max(a[x].ma*a[y].mi,a[x].mi*a[y].ma);
        ll t3=min(a[x].ma*a[y].ma,a[x].mi*a[y].mi);
        ll t4=min(a[x].ma*a[y].mi,a[x].mi*a[y].ma);
        a[x].ma=max(a[x].ma,a[y].ma);
        a[x].mi=min(a[y].mi,a[x].mi);
        ans1[w]+=a[x].len*a[y].len;
        a[x].len+=a[y].len;
        fa[y]=x;
        ans2[w]=max(ans2[w],max(t1,t2));
        
    }
    int main(){
        cin>>n;
        scanf("%s",s+1);
        pre();
        for(int i=1;i<=n;++i){
            tmp[i-1].id=i,tmp[i-1].v=H[i];
        }
        sort(tmp+1,tmp+n);
        for(int i=1;i<=n;++i)scanf("%lld",&c[i]);
        for(int i=1;i<=n;++i){
            a[i].mi=a[i].ma=c[sa[i]];
            a[i].l=a[i].r=i;a[i].len=1;
            fa[i]=i;
        }
        //for(int i=1;i<=n;++i)cout<<sa[i]<<' '<<H[i]<<endl;
        for(int i=0;i<=n;++i)ans2[i]=-inf;
        for(int i=n-1;i>=1;--i){
            merge(tmp[i].id-1,tmp[i].id,tmp[i].v);
        }
        for(int i=n-2;i>=0;--i){
            ans1[i]+=ans1[i+1];
            ans2[i]=max(ans2[i],ans2[i+1]);
        }
        for(int i=0;i<=n-1;++i){
            printf("%lld ",ans1[i]);
            if(ans2[i]==-inf)printf("%lld
    ",0);
            else printf("%lld
    ",ans2[i]);
        }
        return 0;
    }
  • 相关阅读:
    JUC学习笔记--从阿里Java开发手册学习线程池的正确创建方法
    1.初识Python
    学会 Debug
    如何找出nginx配置文件的所在位置?
    一个技术人,如何做到比别人更突出
    生产环境如何快速跟踪、分析、定位问题-Java
    如何优化代码中大量的if/else,switch/case?
    UML类图几种关系的总结
    DateUtils常用方法
    如何存储和表示数字—二进制(一)
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8453699.html
Copyright © 2020-2023  润新知