zoukankan      html  css  js  c++  java
  • UVA11107 Life Forms

    V.UVA11107 Life Forms

    这题同上题类似,只不过把“在全部串中出现”变成了“在超过一半(即\(\left\lfloor\dfrac{n}{2}\right\rfloor+1\))个串中出现”。

    这题中我的方法是上题中提到的“two-pointers+单调队列”算法。第一遍跑求出所有满足“出现次数”为\(\left\lfloor\dfrac{n}{2}\right\rfloor+1\)极小区间,因为小区间的\(\min ht_i\)肯定大于大区间的。

    在单调队列求出公共子串长度的最大值后,需要通过关于\(<ans\)的位置分段(即二分中check的方法)来输出答案——因为按照上面的单调队列算法某些子串有可能会被重复输出。

    复杂度\(O(n)\),假如你用DC3算法的话可惜我不会

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int all,n,m,x[200100],y[200100],buc[200100],sa[200100],ht[200100],rk[200100],id[200100],s[200100],occ[200100];
    char str[200100];
    void SA(){
    	for(int i=0;i<=m;i++)buc[i]=0;
    	for(int i=0;i<n;i++)buc[x[i]=s[i]]++;
    	for(int i=1;i<=m;i++)buc[i]+=buc[i-1];
    	for(int i=n-1;i>=0;i--)sa[--buc[x[i]]]=i;
    	for(int k=1;k<n;k<<=1){
    		int num=0;
    		for(int i=n-k;i<n;i++)y[num++]=i;
    		for(int i=0;i<n;i++)if(sa[i]>=k)y[num++]=sa[i]-k;
    		for(int i=0;i<=m;i++)buc[i]=0;
    		for(int i=0;i<n;i++)buc[x[y[i]]]++;
    		for(int i=1;i<=m;i++)buc[i]+=buc[i-1];
    		for(int i=n-1;i>=0;i--)sa[--buc[x[y[i]]]]=y[i];
    		swap(x,y);
    		x[sa[0]]=num=0;
    		for(int i=1;i<n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
    		m=num;
    	}
    	for(int i=0;i<n;i++)rk[sa[i]]=i;
    	for(int i=0,k=0;i<n;i++){
    		if(!rk[i])continue;
    		if(k)k--;
    		int j=sa[rk[i]-1];
    		while(i+k<n&&j+k<n&&s[i+k]==s[j+k])k++;
    		ht[rk[i]]=k;
    	}
    }
    deque<int>q;
    int main(){
    	scanf("%d",&all);
    	while(all){
    		n=0;
    		for(int i=1;i<=all;i++){
    			scanf("%s",str);
    			m=strlen(str);
    			for(int j=0;j<m;j++)id[n]=i,s[n]=(int)str[j]+5,n++;
    			id[n]=-1,s[n]=i,n++;
    		}
    		m='z'+5;
    		SA();
    //		for(int i=0;i<n;i++)printf("%2d ",id[sa[i]]);puts("");
    //		for(int i=0;i<n;i++)printf("%2d ",ht[i]);puts("");
    		int res=0;
    		for(int i=0,j=0,k=0;i<n;i++){
    			while(j<n&&k<all/2+1){
    				if(id[sa[j]]!=-1)k+=!occ[id[sa[j]]]++;
    				while(!q.empty()&&ht[q.back()]>=ht[j])q.pop_back();
    				q.push_back(j++);
    			}
    			while(!q.empty()&&q.front()<=i)q.pop_front();
    			if(k>=all/2+1)res=max(res,ht[q.front()]);
    			if(id[sa[i]]!=-1)k-=!--occ[id[sa[i]]];
    		}
    		if(!res)puts("?");
    		else for(int i=0,j=0;i<n;i=j){
    			if(id[sa[i]]==-1){j++;continue;}
    			int k=0;
    			k+=!occ[id[sa[i]]],occ[id[sa[i]]]=true;
    			for(j=i+1;j<n&&ht[j]>=res;j++)k+=!occ[id[sa[j]]],occ[id[sa[j]]]=true;
    			for(int l=i;l<j;l++)occ[id[sa[l]]]=false;
    			if(k>=all/2+1){for(int l=0;l<res;l++)printf("%c",s[sa[i]+l]-5);puts("");}
    		}
    		for(int i=0;i<n;i++)s[i]=sa[i]=ht[i]=rk[i]=x[i]=y[i]=id[i]=0;
    		scanf("%d",&all);
    		if(all)puts("");
    	}
    	return 0;
    }
    

  • 相关阅读:
    78. Subsets
    93. Restore IP Addresses
    71. Simplify Path
    82. Remove Duplicates from Sorted List II
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    312. Burst Balloons
    程序员社交平台
    APP Store开发指南
    iOS框架搭建(MVC,自定义TabBar)--微博搭建为例
  • 原文地址:https://www.cnblogs.com/Troverld/p/14602347.html
Copyright © 2011-2022 走看看