zoukankan      html  css  js  c++  java
  • CF19C Deletion of Repeats

    奇怪的黑题增加了!

    考虑一个 (O(n^2)) 的做法,从小到大枚举长度然后从左向右移动区间判断是否相等。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define For(i,x,y)for(i=x;i<=(y);i++)
    int a[100005];
    int main()
    {
    	int n,i,len,tot,j,l=0;
    	scanf("%d",&n);
    	For(i,1,n)scanf("%d",&a[i]);
    	a[0]=-1;
    	For(len,1,n>>1)
    	{
    		tot=0;
    		For(i,1,len-1)tot+=a[i]==a[i+len];
    		For(i,0,n-(len<<1))
    		{
    			tot+=(a[i+len]==a[i+(len<<1)])-(a[i]==a[i+len]);
    			if(i+1>=l&&tot==len)l=i+len+1;
    		}
    	}
    	printf("%d
    ",n-l+1);
    	For(i,l,n)printf("%d ",a[i]);
    	return 0;
    }
    

    但我们发现这个做法极其愚蠢,压根没有用到每个字母最多出现十次的性质。考虑一个两个相等的区间,它们不仅相邻,第一个字母也一模一样(废话)。于是可以枚举这个字母,对数最多只有 (45)

    时间复杂度 (O(n))

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100005
    #define Mod 19260817
    #define Base 100003
    #define For(i,x,y)for(i=x;i<=(y);i++)
    bool vis[N];
    vector<int>vec[N];
    pair<int,int>del[1000000];
    int hach[N],a[N],base[N],b[N];
    inline int get(int l,int r)
    {
    	return(hach[r]-1LL*hach[l-1]*base[r-l+1]%Mod+Mod)%Mod;
    }
    int main()
    {
    	int n,i,m,j,l=1,k,u,v,cnt=0,tmp;
    	scanf("%d",&n);
    	base[0]=1;
    	For(i,1,n)
    	{
    		scanf("%d",&a[i]);
    		b[i]=a[i];
    		base[i]=1LL*base[i-1]*Base%Mod;
    	}
    	sort(b+1,b+n+1);
    	m=unique(b+1,b+n+1)-b-1;
    	For(i,1,n)
    	{
    		tmp=lower_bound(b+1,b+m+1,a[i])-b;
    		hach[i]=(1LL*hach[i-1]*Base+tmp)%Mod;
    		vec[tmp].push_back(i);
    	}
    	For(i,1,n)
    	{
    		tmp=lower_bound(b+1,b+m+1,a[i])-b;
    		if(!vis[tmp])vis[tmp]=1;
    		else continue;
    		For(j,0,int(vec[tmp].size())-2)
    		For(k,j+1,int(vec[tmp].size())-1)
    		{
    			u=vec[tmp][j];
    			v=vec[tmp][k];
    			if(get(u,v-1)==get(v,v-u+v-1))del[++cnt]=make_pair(v-u,v);
    			/*printf("%d %d %d
    ",u,v,cnt);*/
    		}
    	}
    	sort(del+1,del+cnt+1);
    	For(i,1,cnt)
    	if(del[i].second-del[i].first>=l)l=del[i].second;
    	printf("%d
    ",n-l+1);
    	For(i,l,n)printf("%d ",a[i]);
    	return 0;
    }
    
  • 相关阅读:
    ajax
    vue 思維導圖
    python项目_log日志的使用
    mysql数据库_serialisers
    常见的时间复杂度及其增长速度比较
    C++中的sort()函数
    用C++实现输入三个整数,中间用逗号隔开
    python——递归函数
    python——函数
    python——可变对象和不可变对象
  • 原文地址:https://www.cnblogs.com/May-2nd/p/14381636.html
Copyright © 2011-2022 走看看