zoukankan      html  css  js  c++  java
  • bzoj 3238 [Ahoi2013]差异 后缀数组+单调栈

    题目大意

    给定长度为n<=500000的字符串S
    (T_i)表示i开始的后缀
    (sum_{1<=i<j<=n}len(T_i)+len(T_j)-2*lcp(T_i,T_j))

    分析

    后缀数组+单调栈

    注意

    long long

    solution

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    typedef long long LL;
    using namespace std;
    const int M=1000007;
    
    char s[M];
    int n;
    LL ans=0;
    
    int sa[M],t[M];
    int rk[M],f[M];
    int sum[M],h[M];
    
    void getsa(){
    	int i,j,p,nw;
    	memset(sum,0,sizeof(sum));
    	for(i=1;i<=n;i++) sum[s[i]]++;
    	for(i=1;i<=500;i++) sum[i]+=sum[i-1];
    	for(i=n;i>0;i--) sa[sum[s[i]]--]=i;
    	for(p=0,i=1;i<=n;i++) rk[sa[i]]=(s[sa[i]]!=s[sa[i-1]])?(++p):(p);
    	for(j=1,nw=p;nw!=n;j<<=1,nw=p){
    		memset(sum,0,sizeof(sum));
    		memcpy(f,rk,sizeof(rk));
    		for(p=0,i=n-j+1;i<=n;i++) t[++p]=i;
    		for(i=1;i<=n;i++) if(sa[i]>j) t[++p]=sa[i]-j;
    		for(i=1;i<=n;i++) sum[f[i]]++;
    		for(i=1;i<=nw;i++) sum[i]+=sum[i-1];
    		for(i=n;i>0;i--) sa[sum[f[t[i]]]--]=t[i];
    		for(p=0,i=1;i<=n;i++) rk[sa[i]]=(f[sa[i]]!=f[sa[i-1]]||f[sa[i]+j]!=f[sa[i-1]+j])?(++p):(p);
    	}
    }
    
    void geth(){
    	int i,j,p=0;//p=0
    	for(i=1;i<=n;i++){
    		j=sa[rk[i]-1];
    		for(;i+p<=n&&j+p<=n&&s[i+p]==s[j+p];p++);
    		h[rk[i]]=p;
    		if(p>0) p--;
    	}
    	h[1]=0;
    }
    
    struct node{
    	int h,num;
    	node(int hh=0,int nn=0){h=hh;num=nn;}
    }st[M];
    int tot=0;
    
    LL solve(){
    	LL res=0;
    	LL cnt=0;
    	int num;
    	for(int i=1;i<=n;i++){
    		num=1;
    		cnt+=h[i];
    		for(;tot>0&&st[tot].h>=h[i];tot--){
    			num+=st[tot].num;
    			cnt-=(LL)(st[tot].h-h[i])*st[tot].num;
    		}
    		st[++tot]=node(h[i],num);
    		res+=cnt;
    	}
    	return res*2;
    }
    
    int main(){	
    	scanf("%s",s+1);
    	n=strlen(s+1);
    	int i;
    	for(i=1;i<=n;i++) ans+=(LL)(n-i+1)*(n-1);
    
    	getsa();
    	geth();
    	LL tp=solve();
    
    	printf("%lld
    ",ans-tp);
    	
    	return 0;
    }
    
  • 相关阅读:
    大数据
    优化
    gnu
    sed
    hadoop部署
    安装 zookeeper
    ansible
    ssh 配置无密码登录
    未完待续
    解正向代理、反向代理、透明代理
  • 原文地址:https://www.cnblogs.com/acha/p/6418048.html
Copyright © 2011-2022 走看看