• BZOJ3879: SvT


    后缀数组裸题,每次的查询单调栈扫一遍就完了。为什么要写虚后缀树= =后缀数组不是自带虚树的结构么= =

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=5e5+5;
    typedef int arr[N];
    arr sa,r,f[19];
    void pre(char*s,int n){
    	static arr c,t;
    	for(int i=0;i<n;++i)
    		++c[s[i]];
    	for(int i=1;i<127;++i)
    		c[i]+=c[i-1];
    	for(int i=n-1;~i;--i)
    		sa[--c[s[i]]]=i;
    	for(int i=1;i<n;++i)
    		r[sa[i]]=r[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);
    	for(int j=1;;j<<=1){
    		int k=j,m=r[sa[n-1]]+1;
    		if(m==n)break;
    		for(int i=0;i<j;++i)
    			t[i]=n-j+i;
    		for(int i=0;i<n;++i)
    			if(sa[i]>=j)
    				t[k++]=sa[i]-j;
    		for(int i=0;i<m;++i)
    			c[i]=0;
    		for(int i=0;i<n;++i)
    			++c[r[i]];
    		for(int i=1;i<m;++i)
    			c[i]+=c[i-1];
    		for(int i=n-1;~i;--i)
    			sa[--c[r[t[i]]]]=t[i];
    		for(int i=0;i<n;++i)
    			t[i]=r[i];
    		r[sa[0]]=0;
    		for(int i=1;i<n;++i)
    			r[sa[i]]=r[sa[i-1]]+(t[sa[i]]!=t[sa[i-1]]||t[sa[i]+j]!=t[sa[i-1]+j]);
    	}
    }
    bool foo(int i,int j){return r[i]<r[j];}
    int ask(int i,int j){
    	int k=__lg(j-i+1);
    	return min(f[k][i],f[k][j-(1<<k)+1]);
    }
    int main(){
    	int n,q,m;
    	static char s[N];
    	scanf("%d%d%s",&n,&q,s);
    	pre(s,n+1);
    	for(int i=0,j=0;i<n;++i){
    		if(j)--j;
    		while(s[i+j]==s[sa[r[i]-1]+j])
    			++j;
    		f[0][r[i]]=j;
    	}
    	for(int j=1;1<<j<n;++j)
    		for(int i=1;i+(1<<j)-1<=n;++i)
    			f[j][i]=min(f[j-1][i],f[j-1][i+(1<<j-1)]);
    	while(q--){
    		static arr a,h,t;
    		static ll z[N];
    		scanf("%d",&m);
    		for(int j=0;j<m;++j)
    			scanf("%d",a+j),--a[j];
    		sort(a,a+m,foo);
    		m=unique(a,a+m)-a;
    		for(int j=1;j<m;++j)
    			h[j]=ask(r[a[j-1]]+1,r[a[j]]);
    		h[m]=-1;
    		for(int j=0;j<m;++j)
    			z[j]=1;
    		ll e=0;
    		for(int i=0,j=1;j<=m;++j){
    			for(;i&&h[j]<=h[t[i]];--i){
    				e+=h[t[i]]*z[t[i-1]]*z[t[i]];
    				z[t[i-1]]+=z[t[i]];
    			}
    			t[++i]=j;
    		}
    		printf("%lld
    ",e);
    	}
    }
    
  • 相关阅读:
    HDU 3389 Game (阶梯博弈)
    HDU1536&&POJ2960 S-Nim(SG函数博弈)
    HDU 2089 不要62(数位DP)
    ACdream 1210 Chinese Girls' Amusement(高精度)
    CodeForces 659D Bicycle Race (判断点是否为危险点)
    HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)
    手动删除Win7系统服务列表中残留服务的操作步骤
    C++学习37 string字符串的访问和拼接
    C++学习36 string类和字符串
    C++学习35 模板中的函数式参数
  • 原文地址:https://www.cnblogs.com/f321dd/p/6233867.html
Copyright © 2020-2023  润新知