zoukankan      html  css  js  c++  java
  • Codeforces 666E Forensic Examination SAM+权值线段树

    第一次做这种(SAM)带权值线段树合并的题 然而(zjq)神犇看完题一顿狂码就做出来了 (Orz)

    首先把所有串当成一个串建(SAM) 我们对(SAM)上每个点 建一棵权值线段树 每个叶子节点表示一个匹配串能到达这个点的子串个数 这样我们对最后的(SAM)的权值线段树按(parent)树合并 询问的时候找到对应的(SAM)上的权值线段树直接查询就好了

    具体的操作看代码吧~

    #include<bits/stdc++.h>
    using namespace std;
    #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
    #define pa pair<int,int>
    #define mod 1000000007
    #define ll long long
    #define mk make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define cl(x) memset(x,0,sizeof x)
    #ifdef Devil_Gary
    #define bug(x) cout<<(#x)<<" "<<(x)<<endl
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    #else
    #define bug(x)
    #define debug(...)
    #endif
    const int INF = 0x7fffffff;
    const int N=1230010;
    /*
    char *TT,*mo,but[(1<<15)+2];
    #define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
    inline int read(){
        int x=0,rev=0,ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return rev?-x:x;
    }
    pa operator * (const pa&A,const pa&B){return A.fi==B.fi?(A.se<B.se?A:B):(A.fi>B.fi?A:B);}
    pa operator + (const pa&A,const pa&B){return mk(A.fi+B.fi,A.se);}
    pa t[N*23];
    char s[N];
    int n,m,Q,c[N][27],par[N],len[N],fa[N][21],ls[N*23],rs[N*23],h[N],rt=1,sz=1,last=1,root[N],w[N],b[N],id; 
    void extend(int x){
    	int np=++sz,p=last;
    	len[np]=len[p]+1,last=np;
    	for(;p&&!c[p][x];p=par[p]) c[p][x]=np;
    	if(!p) par[np]=rt;
    	else{
    		int q=c[p][x];
    		if(len[p]+1==len[q]) par[np]=q;
    		else{
    			int nq=++sz;
    			len[nq]=len[p]+1,par[nq]=par[q],par[q]=par[np]=nq;
    			memcpy(c[nq],c[q],sizeof c[nq]);
    			for(;p&&c[p][x]==q;p=par[p]) c[p][x]=nq;
    		}
    	}
    }
    void modify(int&pos,int l,int r,int x){
    	if(!pos) pos=++id; 
    	if(l==r){
    		t[pos].fi++,t[pos].se=l;
    //		cout<<t[pos].fi<<" "<<t[pos].se<<endl;
    		return;
    	}
    	int mid=l+r>>1;
    	if(x<=mid) modify(ls[pos],l,mid,x);
    	else modify(rs[pos],mid+1,r,x);
    	t[pos]=t[ls[pos]]*t[rs[pos]];
    }
    inline int merge(int x,int y,int l,int r)
    {
        if (!x||!y) return x|y;	
        int z=++id;
        if (l==r) {
            t[z]=t[x]+t[y];
            return z;
        }
        int mid=(l+r)>>1;
        ls[z]=merge(ls[x],ls[y],l,mid),rs[z]=merge(rs[x],rs[y],mid+1,r);
        t[z]=t[ls[z]]*t[rs[z]];
        return z;
    }
    pa Query(int pos,int l,int r,int nl,int nr){
    	if(!pos) return mk(0,0);
    	if(nl<=l&&r<=nr) return t[pos];
    	int mid=l+r>>1;
    	if(nr<=mid) return Query(ls[pos],l,mid,nl,nr);
    	else if(nl>mid) return Query(rs[pos],mid+1,r,nl,nr);
    	else return Query(ls[pos],l,mid,nl,nr)*Query(rs[pos],mid+1,r,nl,nr);
    }
    void topsort(){
    	for(int i=1;i<=sz;i++) w[len[i]]++;
    	for(int i=1;i<=sz;i++) w[i]+=w[i-1];
    	for(int i=1;i<=sz;i++) b[w[len[i]]--]=i;
    	for(int i=sz;i;i--){
    		int j=b[i];
    		if(par[j]) root[par[j]]=merge(root[par[j]],root[j],1,n);
    	}
    }
    void get_fa(){
    	for(int i=1;i<=sz;i++) fa[i][0]=par[i];
    	for(int i=1;i<=20;i++) for(int j=1;j<=sz;j++) fa[j][i]=fa[fa[j][i-1]][i-1];
    }
    int get(int l,int r){
    	int L=r-l+1,x=h[r];
    	for(int i=20;~i;i--) if(len[fa[x][i]]>=L) x=fa[x][i];
    //	-len[par[x]]-len[par[fa[x][i]]]
    	return x;
    }
    int main(){
    #ifdef Devil_Gary
    	freopen("in.txt","r",stdin);
    #endif
    	scanf("%s",s+1),m=strlen(s+1);
    	for(int i=1;i<=m;i++) extend(s[i]-'a'),h[i]=last;
    	n=read();
    	for(int i=1;i<=n;i++){
    		scanf("%s",s+1),m=strlen(s+1),extend(26);
    		for(int j=1;j<=m;j++) extend(s[j]-'a'),modify(root[last],1,n,i);
    	}
    //	bug(sz);
    	topsort(),get_fa();
    	for(Q=read();Q;Q--){
    		int l=read(),r=read(),pl=read(),pr=read(),x=get(pl,pr);
    		pa ans=Query(root[x],1,n,l,r);
    		if(!ans.fi) printf("%d 0
    ",l);
    		else printf("%d %d
    ",ans.se,ans.fi);
    	} 
    }
    
    
    
  • 相关阅读:
    Charles的基本功能使用
    模拟器的代理功能
    LoadRunner参数包含逗号
    MySQL 与 [charlist]% 通配符
    MySQL 删除重复项并保留其中一个
    Selenium grid 分布式测试搭建(二)
    Selenium grid 分布式测试搭建(一)
    chromedriver与chrome版本映射表 与chromedriver 下载地址
    Selenium 打开 Chrome 链接框只有 Data;
    Xpath 小结
  • 原文地址:https://www.cnblogs.com/devil-gary/p/9057102.html
Copyright © 2011-2022 走看看