zoukankan      html  css  js  c++  java
  • HDU 6704 K-th occurrence (后缀数组+二分+主席树)

    传送门

    思路

    走一遍后缀数组后,可以发现要求的就是与 (rk[i])(lcpgeq r-l+1) 的这段区间的数中第 (k) 大的 (sa)
    那么可以构建好主席树后,二分找出要求区间,然后再主席树上找第 (k) 大的值就完成了这道题

    为了搞这道题我啃了好久的后缀数组,做出了题后才发现这道题其实蛮模板的,蛤蛤

    代码

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    using namespace std;
    const int MAXN=1e5+10;
    int T,n,q,m,sa[MAXN],rk[MAXN*2],tp[MAXN*2],c[MAXN],ht[MAXN];
    int st[MAXN][22];
    int rt[MAXN];
    char s[MAXN];
    
    struct HjtTree{
    	#define mid ((l+r)>>1)
    	int L[MAXN*20],R[MAXN*20],siz[MAXN*20],tot;
    	
    	void build(int &id,int l,int r){
    		id=++tot;
    		siz[id]=0;
    		if(l==r) return;
    		build(L[id],l,mid);
    		build(R[id],mid+1,r);
    	} 
    	
    	void update(int pre,int &id,int l,int r,int x){
    		id=++tot;
    		L[id]=L[pre],R[id]=R[pre],siz[id]=siz[pre]+1;
    		if(l==x&&r==x) return;
    		if(x<=mid) update(L[pre],L[id],l,mid,x);
    		else update(R[pre],R[id],mid+1,r,x);
    	}
    	
    	int ask(int u,int v,int l,int r,int k){
    		if(l==r) return l;
    		int lsiz=siz[L[v]]-siz[L[u]];
    		if(k<=lsiz) return ask(L[u],L[v],l,mid,k);
    		else return ask(R[u],R[v],mid+1,r,k-lsiz);
    	}
    }tree;
    
    void getsa(){
    	m='z';
    	for(int i=1;i<=n;i++) c[rk[i]=s[i]]++;
    	for(int i=1;i<=m;i++) c[i]+=c[i-1];
    	for(int i=1;i<=n;i++) sa[c[rk[i]]--]=i;
    	for(int w=1,p=0;p<n;w<<=1,m=p){
    		p=0;
    		for(int i=n-w+1;i<=n;i++) tp[++p]=i;
    		for(int i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
    		for(int i=1;i<=m;i++) c[i]=0;
    		for(int i=1;i<=n;i++) c[rk[i]]++;
    		for(int i=1;i<=m;i++) c[i]+=c[i-1];
    		for(int i=n;i>=1;i--) sa[c[rk[tp[i]]]--]=tp[i];
    		swap(rk,tp);
    		rk[sa[1]]=p=1;
    		for(int i=2;i<=n;i++)
    			rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;
    	}
    }
    
    void getheight(){
    	int k=0;
    	for(int i=1;i<=n;i++){
    		if(rk[i]==1) continue;
    		if(k) k--;
    		int j=sa[rk[i]-1];
    		while(j+k<=n&&i+k<=n&&s[j+k]==s[i+k]) k++;
    		ht[rk[i]]=k;
    	}
    }
    
    int lcp(int x,int y){
    	int l=rk[x],r=rk[y];
    	if(l>r) swap(l,r);
    	if(l==r) return n-x+1;
    	int t=log2(r-l);
    	return min(st[l+1][t],st[r-(1<<t)+1][t]);
    }
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		memset(sa,0,sizeof(sa));
    		memset(rk,0,sizeof(rk));
    		memset(tp,0,sizeof(tp));
    		memset(c,0,sizeof(c));
    		memset(ht,0,sizeof(ht));
    		memset(st,0,sizeof(st));
    		memset(tree.siz,0,sizeof(tree.siz));
    		memset(tree.L,0,sizeof(tree.L));
    		memset(tree.R,0,sizeof(tree.R));
    		memset(rt,0,sizeof(rt));
    		scanf("%d%d",&n,&q);
    		scanf("%s",s+1);
    		getsa();
    		getheight();
    		tree.tot=0;
    		tree.build(rt[0],1,n);
    		for(int i=1;i<=n;i++) tree.update(rt[i-1],rt[i],1,n,sa[i]);
    		for(int i=1;i<=n;i++) st[i][0]=ht[i];
    		for(int j=1;j<=20;j++)
    			for(int i=1;i+(1<<j)-1<=n;i++)
    				st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    		while(q--){
    			int x,y,k;
    			scanf("%d%d%d",&x,&y,&k);
    			int len=y-x+1;
    			int l=1,r=rk[x];
    			while(l<r){
    				int md=(l+r)>>1;
    				if(lcp(sa[md],x)>=len) r=md;
    				else l=md+1;
    			}
    			int low=l;
    			l=rk[x],r=n;
    			while(l<r){
    				int md=(l+r+1)>>1;
    				if(lcp(x,sa[md])>=len) l=md;
    				else r=md-1;
    			}
    			int high=l;
    			if(high-low+1<k) printf("-1
    ");
    			else printf("%d
    ",tree.ask(rt[low-1],rt[high],1,n,k));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    使用插件和不使用插件实现select的框
    利用sshtunnel实现跳板机的效果[嵌套ssh实现]
    laravel中get()与 first()区别、collection与stdClass的区别
    Laravel 安全:避免 SQL 注入
    MAC 终端走代理服务器
    Python--Virtualenv简明教程(转载https://www.jianshu.com/p/08c657bd34f1)
    Charles 如何抓取https数据包
    爬虫出现Forbidden by robots.txt(转载 https://blog.csdn.net/zzk1995/article/details/51628205)
    Scrapy框架的学习(6.item介绍以及items的使用(提前定义好字段名))转载https://blog.csdn.net/wei18791957243/article/details/86259688
    python xpath
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11982631.html
Copyright © 2011-2022 走看看