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

    巨大缝合题(逃
    先考虑(k)小操作啊,(SAM)除去(link)后,这个东西就类似于一颗(tire)
    就在(tire)上跑就好了。
    不过要预处理出每个等价类的出现次数。
    这题充分揭示了后缀(tire)(SAM)的关系,(SAM)实际上为路径压缩后的后缀(tire)树的聚合体。

    [TJOI2015]弦论
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define N 500005
    
    ll link[N << 1],ch[N << 1][30],f[N << 1],g[N << 1],len[N << 1];
    
    char a[N];
    
    ll nod = 1,lst = 1;
    
    inline void insert(int c){
    	int p = lst,q = ++nod;lst = q;
    	len[q] = len[p] + 1;
    	while(!ch[p][c] && p != 0){//向上找 
    		ch[p][c] = q;
    		p = link[p];
    	} 
    	if(p == 0)
    	link[q] = 1;
    	else{
    		int x = ch[p][c];
    		if(len[p] + 1 == len[x]){
    			link[q] = x;
    		}else{
    			int y = ++ nod ;//复制一个新节点
    			link[y] = link[x];
    			link[x] = link[q] = y;
    			len[y] = len[p] + 1;
    			std::memcpy(ch[y],ch[x],sizeof(ch[x])); 
    			while(p != 0 && ch[p][c] == x){
    				ch[p][c] = y;
    				p = link[p];
    			}
    		}
    	}
    }
    
    ll cnt,head[N << 1];
    struct P{int to,next;}e[N << 1];
    
    inline void add(int x,int y){
    	e[++cnt].to = y;
    	e[cnt].next = head[x];
    	head[x] = cnt;
    }
    
    inline void dfs(int u){
    	if(head[u] == 0){
    		f[u] = 1;
    		return;
    	}
    	for(int i = head[u];i;i = e[i].next){
    		dfs(e[i].to);
    		f[u] += f[e[i].to];
    	}
    }
    
    ll t,k;
    bool vis[N << 1];
    
    inline void dfs2(int u){
    	if(vis[u])
    	return ;
    	vis[u] = 1;
    	for(int i = 0;i <= 26;++i){
    		if(!ch[u][i])
    		continue;
    		dfs2(ch[u][i]);
    		g[u] += g[ch[u][i]];
    	}
    }
    
    inline void Print(int u,int k){
    //	std::cout<<u<<" "<<k<<" "<<f[u]<<std::endl;
    	if(k <= f[u])return ;else k -= f[u];
    	for(int i = 0;i <= 26;++i){
    		if(!ch[u][i])
    		continue;
    		if(g[ch[u][i]] >= k){
    		std::cout<<(char)('a' + i);
    		Print(ch[u][i],k);
    		return;
    		}
    		else
    		k -= g[ch[u][i]];
    	}
    }
    
    int main(){
    	freopen("q.in","r",stdin);
    	freopen("q.out","w",stdout);
    	scanf("%s",a + 1);
    	ll l = std::strlen(a + 1);
    	scanf("%lld%lld",&t,&k);
    	for(int i = 1;i <= l;++i)
    	insert(a[i] - 'a');
    	for(int i = 1;i <= nod;++i)
    	add(link[i],i);
    	dfs(1);
    	for(int i = 1;i <= nod;++i)
    	g[i] = (t) ? f[i] : (f[i] = 1);
    	f[1] = g[1] = 0;
    	dfs2(1);
    	for(int i = 1;i <= nod;++i)
    	std::cout<<f[i]<<" "<<g[i]<<std::endl;
    	if(k > g[1]){
    		puts("-1");
    		return 0;
    	}
    	Print(1,k);
    }
    
    
  • 相关阅读:
    5.3 存储器、I/O和配置读写请求TLP 分类: 浅谈PCI-E 2013-07-22 16:28 413人阅读 评论(0) 收藏
    5.2 TLP的路由 分类: 浅谈PCI-E 2013-07-22 16:28 337人阅读 评论(0) 收藏
    5.1 TLP的格式 分类: 浅谈PCI-E 2013-07-22 16:27 464人阅读 评论(0) 收藏
    第5章 PCIe总线的事务层 分类: 浅谈PCI-E 2013-07-22 16:27 345人阅读 评论(0) 收藏
    1016. Phone Bills (25)
    1018. Public Bike Management (30)
    1076. Forwards on Weibo (30)
    1034. Head of a Gang (30)
    1021. Deepest Root (25)
    1013. Battle Over Cities (25)
  • 原文地址:https://www.cnblogs.com/dixiao/p/14873017.html
Copyright © 2011-2022 走看看