zoukankan      html  css  js  c++  java
  • BZOJ3998 [TJOI2015]弦论 SAM

    建一个(SAM) 如果(T=0)也就是本质不同的串直接在(SAM)上统计就好 如果(T=1)先拓扑序用(parent)树转移求出本质相同的串

    后面都是做相同的(dfs)求出结果就好

    #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 fisrt
    #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=1e6+5;
    /*
    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;
    }
    int T,tot,n,k,rt,sum[N<<1],last,par[N<<1],c[N<<1][26],len[N<<1],sz[N<<1],b[N<<1],w[N];
    char s[N];
    void extend(int x){
    	int p=last,np=++tot;len[np]=len[p]+1;sz[np]=1;
    	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[q]==len[p]+1) par[np]=q;
    		else {
    			int nq=++tot;
    			len[nq]=len[p]+1;
    			memcpy(c[nq],c[q],sizeof c[q]);
    			par[nq]=par[q],par[q]=par[np]=nq;
    			for(;p&&c[p][x]==q;p=par[p]) c[p][x]=nq;
    		}
    	} 
    	last=np;
    }
    void dfs(int x){
    	if(k<=sz[x]) return ;
    	k-=sz[x];
    #define sz sum
    	for(int i=0;i<26;i++){
    		if(!sz[c[x][i]]) continue;
    		if(sz[c[x][i]]<k) k-=sz[c[x][i]];
    		else {
    			putchar(i+'a');
    			dfs(c[x][i]);
    			return;
    		}
    	}
    #undef sz
    }
    int main(){
    #ifdef Devil_Gary
    	freopen("in.txt","r",stdin);
    #endif
    	scanf("%s",s+1),n=strlen(s+1),rt=tot=last=1,T=read(),k=read();
    	for(int i=1;i<=n;i++) extend(s[i]-'a');
    	for(int i=1;i<=tot;i++) w[len[i]]++;
    	for(int i=1;i<=n;i++) w[i]+=w[i-1];
    	for(int i=1;i<=tot;i++) b[w[len[i]]--]=i;
    	for(int i=tot;i>1;i--){
    		int j=b[i];
    		if(T)sz[par[j]]+=sz[j];
    		else sz[j]=1;
    	}
    	bug(sz[rt]);
    	sz[rt]=0;
    	for(int i=tot;i;i--){
    		int k=b[i]; 
    		sum[k]=sz[k];
    		for(int j=0;j<26;j++){
    			if(c[k][j]) sum[k]+=sum[c[k][j]];
    		}
    	}
    	bug(sum[rt]);
    	if(k>sum[rt]) return puts("-1"),0;
    	dfs(rt);
    }
    
  • 相关阅读:
    python3.7版本安装pyinstaller
    Redis
    电商路演
    前台Vue、后台Django、设置axios解决csrf_token问题
    企业为什么要设置中台
    2021.1.11 学习总结
    2021.1.10 学习总结
    2021.1.9 学习总结
    2021.1.8 学习总结
    2021.1.7 学习总结
  • 原文地址:https://www.cnblogs.com/devil-gary/p/8891162.html
Copyright © 2011-2022 走看看