zoukankan      html  css  js  c++  java
  • NOI2015 品酒大会

    NOI2015 品酒带会

    看到就知道咋做了吧。。。

    在parent树上的LCA处统计答案就好了,因为两个子串的lcs(后缀的lcp)在parent树上位置是在LCA处,所以对于每个点找一下来自不同子树(使LCA等于它)更新答案,然后取后缀max(和)

    这里从后往前插入会比较方便

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const ll inf = 9223372036854775803;
    int read(){
    	int x=0,pos=1;char ch=getchar();
    	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
    	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    	return pos?x:-x; 
    } 
    const int N = 1000201;
    ll a[N],b[N],mx[N],ans[N],tms[N],mi[N];
    ll ti[N],lnk[N],sz[N];
    char s[N];
    int n;
    struct tree{
    	int ch[26],fa,len;
    }t[N];
    int las=1,tot=1;
    void insert(int c,int id){
    	int p=las,np=las=++tot;
    	t[np].len=t[p].len+1;sz[np]=1;mx[np]=mi[np]=a[id];
    	for(;p&&!t[p].ch[c];p=t[p].fa) t[p].ch[c]=np;
    	if(!p) t[np].fa=1;
    	else{
    		int q=t[p].ch[c];
    		if(t[p].len+1==t[q].len) t[np].fa=q;
    		else{
    			int nq=++tot;
    			t[nq]=t[q];t[nq].len=t[p].len+1;
    			t[np].fa=t[q].fa=nq;
    			for(;t[p].ch[c]==q;p=t[p].fa) t[p].ch[c]=nq;
    		}
    	}
    }
    struct node{
    	int v,nex;
    }edge[N<<1];
    int head[N],top=0;
    void add(int u,int v){
    	edge[++top].v=v;
    	edge[top].nex=head[u];
    	head[u]=top;
    } 
    void dfs(int now){
    	for(int i=head[now];i;i=edge[i].nex){
    		int v=edge[i].v;
    		dfs(v);tms[t[now].len]+=sz[now]*sz[v];
    		sz[now]+=sz[v];
    		if(mx[now]!=-inf) ans[t[now].len]=max(ans[t[now].len],mx[now]*mx[v]);
    		if(mi[now]!=inf) ans[t[now].len]=max(ans[t[now].len],mi[now]*mi[v]);
    		mx[now]=max(mx[now],mx[v]);mi[now]=min(mi[now],mi[v]);
    	}
    }
    int main(){
    	//freopen("1.in","r",stdin);
    	//freopen("1.txt","w",stdout);
    	n=read();
    	scanf("%s",s+1);
    	for(int i=1;i<=n;i++){
    		a[i]=read();
    	}
    	for(int i=1;i<N;i++){
    		mx[i]=-inf;mi[i]=inf,ans[i]=-inf;
    	}
    	for(int i=n;i>=1;i--){
    		insert(s[i]-'a',i);
    	}
    	for(int i=1;i<=tot;i++) add(t[i].fa,i);
    	dfs(1);
    	for(int i=n-1;i>=1;i--) tms[i-1]+=tms[i],ans[i-1]=max(ans[i-1],ans[i]);
    	for(int i=0;i<=n-1;i++){
    		printf("%lld %lld
    ",tms[i],(ans[i]==-inf)?0:ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    (基础篇)正则表达式的语法汇总与详细介绍
    (基础篇) 正则表达式详解
    (基础篇)PHP字符串操作
    (基础篇)PHP流程控制语句
    CentOS 7.0 安装配置 kafka 消息队列
    配置 Gitblit 进行 Git 代码管理
    nexus 中央仓库
    svn + jenkins + maven 实现java环境的自动化构建和部署
    Mariadb galera 群集
    Jboss 集群配置
  • 原文地址:https://www.cnblogs.com/lcyfrog/p/12289086.html
Copyright © 2011-2022 走看看