zoukankan      html  css  js  c++  java
  • BZOJ 5137: [Usaco2017 Dec]Standing Out from the Herd(后缀自动机)

    传送门

    解题思路

      这个似乎和以前做过的一道题很像,只不过这个是求本质不同子串个数。肯定是先把广义(SAM)造出来,然后(dfs)时把子节点的信息合并到父节点上,看哪个只被一个串覆盖,(ans+=l_i-l_{fa_i})。这里我比较懒(sha),合并信息直接暴力扔了个(set)启发式合并上去的,似乎分类讨论一下就行了,平添(log)正是在下。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<string>
    #include<vector>
    
    using namespace std;
    const int N=100005;
    typedef long long LL;
    
    int n,a[N<<1],c[N<<1],siz[N<<1];
    LL ans[N];
    set<int> S[N<<1];
    vector<int> v[N<<1];
    string s[N];
    
    void add(int bg,int ed){
    	v[bg].push_back(ed);
    }
    
    void dfs(int x){
    	int u;
    	for(int i=0;i<v[x].size();i++){
    		u=v[x][i]; dfs(u);
    		if(x==1) continue;
    		for(set<int>::iterator it=S[u].begin();it!=S[u].end();it++)
    			S[x].insert(*it);
    	}
    	siz[x]=S[x].size();
    }
    
    struct SAM{
    	int fa[N<<1],ch[N<<1][28],l[N<<1],cnt,lst;
    	void Insert(int c,int id){
    		int p=lst,np=++cnt; l[np]=l[p]+1; lst=cnt;
    		for(;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    		if(!p) fa[np]=1;
    		else {
    			int q=ch[p][c]; 
    			if(l[q]==l[p]+1) fa[np]=q;
    			else {
    				int nq=++cnt; l[nq]=l[p]+1;
    				memcpy(ch[nq],ch[q],sizeof(ch[nq]));
    				fa[nq]=fa[q]; fa[q]=fa[np]=nq;
    				for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    			}
    		} 
    		S[np].insert(id);
    	}
    	void solve(){
    		for(int i=1;i<=cnt;i++)
    			if(fa[i]) add(fa[i],i);
    		dfs(1);
    	}
    }sam;
    
    int main(){
    	scanf("%d",&n); int len; sam.cnt=1;
    	for(int i=1;i<=n;i++){
    		cin>>s[i]; len=s[i].length(); sam.lst=1; 
    		for(int j=0;j<len;j++) sam.Insert(s[i][j]-'a'+1,i);
    	}
    	sam.solve();
    	for(int i=1;i<=sam.cnt;i++)
    		if(siz[i]==1) ans[*S[i].begin()]+=sam.l[i]-sam.l[sam.fa[i]];
    	for(int i=1;i<=n;i++) printf("%lld
    ",ans[i]);
    	return 0;
    }	
    
  • 相关阅读:
    算法之冒泡排序
    实现秒杀的几个想法(续)
    乐观锁
    wifi-sdio接口
    解压vmlinuz和解压initrd(initramfs)
    supplicant
    wpa_supplicant测试
    qu
    netlink
    wpa_supplicant安装
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10453563.html
Copyright © 2011-2022 走看看