zoukankan      html  css  js  c++  java
  • 【POJ 3261】Milk Patterns

    【链接】h在这里写链接


    【题意】


    给你一个长度为n的序列。
    问你能不能在其中找到一个最长的子串。
        这个子串至少出现了k次.

    【题解】


    长度越长,就越不可能出现k次
    后缀数组+二分。
    N最大为20000;
    每个数字在0到1e5之间
    防止出错,把那个数字都加上1就好
    (因为N比每个数字的大小来的小,所以需要把N也开到1E5以上。)

    【错的次数】


    0

    【反思】


    在这了写反思

    【代码】

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N = 2e5;
    const int MAX_CHAR = 1e5+10;//每个数字的最大值。
    int s[N + 10];//如果是数字,就写成int s[N+10]就好,从0开始存
    int Sa[N + 10], T1[N + 10], T2[N + 10], C[N + 10];
    int Height[N + 10], Rank[N + 10];
    
    void build_Sa(int n, int m) {
    	int i, *x = T1, *y = T2;
    	for (i = 0; i<m; i++) C[i] = 0;
    	for (i = 0; i<n; i++) C[x[i] = s[i]]++;
    	for (i = 1; i<m; i++) C[i] += C[i - 1];
    	for (i = n - 1; i >= 0; i--) Sa[--C[x[i]]] = i;
    	for (int k = 1; k <= n; k <<= 1)
    	{
    		int p = 0;
    		for (i = n - k; i<n; i++) y[p++] = i;
    		for (i = 0; i<n; i++) if (Sa[i] >= k) y[p++] = Sa[i] - k;
    		for (i = 0; i<m; i++) C[i] = 0;
    		for (i = 0; i<n; i++) C[x[y[i]]]++;
    		for (i = 1; i<m; i++) C[i] += C[i - 1];
    		for (i = n - 1; i >= 0; i--) Sa[--C[x[y[i]]]] = y[i];
    		swap(x, y);
    		p = 1; x[Sa[0]] = 0;
    		for (i = 1; i<n; i++)
    			x[Sa[i]] = y[Sa[i - 1]] == y[Sa[i]] && y[Sa[i - 1] + k] == y[Sa[i] + k] ? p - 1 : p++;
    		if (p >= n) break;
    		m = p;
    	}
    }
    
    void getHeight(int n)
    {
    	int i, j, k = 0;
    	for (i = 1; i <= n; i++) Rank[Sa[i]] = i;
    	for (i = 0; i<n; i++) {
    		if (k) k--;
    		j = Sa[Rank[i] - 1];
    		while (s[i + k] == s[j + k]) k++;
    		Height[Rank[i]] = k;
    	}
    }
    
    int n, k;
    
    bool ok(int l)
    {
    	int cnt = 0;
    	for (int i = 2; i <= n; i++)
    		if (Height[i] >= l)
    		{
    			cnt++;
    			if (cnt >= k - 1) return true;
    		}
    		else
    		{
    			cnt = 0;
    		}
    	return false;
    }
    
    int main()
    {
    	//freopen("F:\rush.txt", "r", stdin);
    	scanf("%d%d", &n, &k);
    	for (int i = 0; i < n; i++)
    	{
    		scanf("%d", &s[i]);
    		s[i]++;
    	}
    	s[n] = 0;
    	build_Sa(n + 1, MAX_CHAR);
    	getHeight(n);
    
    	int l = 1, r = n, temp = 0;
    	while (l <= r)
    	{
    		int mid = (l + r) >> 1;
    		if (ok(mid))
    		{
    			temp = mid;
    			l = mid + 1;
    		}
    		else
    			r = mid - 1;
    	}
    	printf("%d
    ", temp);
    	return 0;
    }


  • 相关阅读:
    Spring MVC 核心组件详解
    Spring MVC 入门就这一篇
    Spring 事务解决方案
    【UGUI源码分析】Unity遮罩之Mask详细解读
    游戏开发中不同时区下的时间问题
    ARTS第十三周(阅读Tomcat源码)
    Win10 电脑安装.NET低版本提示“这台计算机中已经安装了 .NET Framwork 4.6.2或版本更高的更新”问题
    Dynamics 365 Setup 提示SqlServer 存在
    Dynamics CRM "Verification of prerequisites for Domain Controller promotion failed. Certificate Server is installed."
    Dynamics CRM
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7625990.html
Copyright © 2011-2022 走看看