zoukankan      html  css  js  c++  java
  • 【CF 547E】 Mike and Friends

    题目

    显然SAM版题,写它的原因就是我太颓了;之后学习了一下正规的广义SAM写法,争取以后不再写lst=1

    代码

    #include<bits/stdc++.h>
    #define re register
    const int maxn=4e5+5;
    const int M=maxn*30;
    struct E{int v,nxt;}e[maxn];char S[maxn>>1];
    int l[M],r[M],d[M],tot,q;
    int lst,cnt,n,L,num,dep[maxn],lg[maxn],head[maxn],f[20][maxn];
    int fa[maxn],son[maxn][26],len[maxn],rt[maxn],pos[maxn>>1],ln[maxn>>1];
    inline void add(int x,int y) {
    	e[++num].v=y;e[num].nxt=head[x];head[x]=num;
    }
    int chg(int nw,int x,int y,int pos) {
    	if(!nw)nw=++tot;d[nw]++;if(x==y)return nw;int mid=x+y>>1;
    	pos<=mid?l[nw]=chg(l[nw],x,mid,pos):r[nw]=chg(r[nw],mid+1,y,pos);return nw;
    }
    int merge(int a,int b,int x,int y) {
    	if(!a||!b)return a|b;int nw=++tot;
    	if(x==y) {d[nw]=d[a]+d[b];return nw;}int mid=x+y>>1;
    	l[nw]=merge(l[a],l[b],x,mid);r[nw]=merge(r[a],r[b],mid+1,y);
    	d[nw]=d[l[nw]]+d[r[nw]];return nw;
    }
    int qry(int nw,int x,int y,int lx,int ry) {
    	if(!nw)return 0;if(lx<=x&&ry>=y)return d[nw];int mid=x+y>>1;
    	return (lx<=mid?qry(l[nw],x,mid,lx,ry):0)+(ry>mid?qry(r[nw],mid+1,y,lx,ry):0);
    }
    void dfs(int x) {
    	for(re int i=1;i<=lg[dep[x]];++i)f[i][x]=f[i-1][f[i-1][x]];
    	for(re int i=head[x];i;i=e[i].nxt) 
    		dep[e[i].v]=dep[x]+1,dfs(e[i].v),rt[x]=merge(rt[x],rt[e[i].v],1,n);
    }
    inline void ins(int c) {
    	if(son[lst][c]) {
    		int f=lst,x=son[f][c];
    		if(len[f]+1==len[x]) {lst=x;return;}
    		int y=++cnt;len[y]=len[f]+1;fa[y]=fa[x];fa[x]=y;
    		for(re int i=0;i<26;i++)son[y][i]=son[x][i];
    		while(f&&son[f][c]==x)son[f][c]=y,f=fa[f];
    		lst=y;return;
    	}	
    	int p=++cnt,f=lst;lst=p;len[p]=len[f]+1;
    	while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
    	if(!f){fa[p]=1;return;}
    	int x=son[f][c];
    	if(len[f]+1==len[x]){fa[p]=x;return;}
    	int y=++cnt;len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
    	for(re int i=0;i<26;i++)son[y][i]=son[x][i];
    	while(f&&son[f][c]==x)son[f][c]=y,f=fa[f];
    }
    int main() {
    	scanf("%d%d",&n,&q);cnt=1;
    	for(re int i=1;i<=n;i++) {
    		scanf("%s",S+1);int L=strlen(S+1);lst=1;ln[i]=L;
    		for(re int j=1;j<=L;++j) ins(S[j]-'a'),rt[lst]=chg(rt[lst],1,n,i);
    		pos[i]=lst;
    	}
    	for(re int i=2;i<=cnt;i++)add(fa[i],i),f[0][i]=fa[i];
    	for(re int i=2;i<=cnt;i++)lg[i]=lg[i>>1]+1;
    	dep[1]=1,dfs(1);int x,y,k,lim;
    	while(q--) {
    		scanf("%d%d%d",&x,&y,&k);lim=ln[k],k=pos[k];
    		for(re int j=lg[dep[k]];j>=0;--j)k=len[f[j][k]]>=lim?f[j][k]:k;
    		printf("%d
    ",qry(rt[k],1,n,x,y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    underscorejs
    使用CORS:跨域两三事
    line-height的小技巧
    深入探讨ES6生成器
    ES6生成器基础
    响应式网页
    javascript代码复用(四)-混入、借用方法和绑定
    javascript代码复用模式(三)
    javascript代码复用模式(二)
    jQuery基础事件
  • 原文地址:https://www.cnblogs.com/asuldb/p/12219350.html
Copyright © 2011-2022 走看看