zoukankan      html  css  js  c++  java
  • [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)

    传送门

    很容易想到,题目中的相同是指差分数组相同。

    那么可以把差分数组连起来,中间加上一个没有出现过的且字典序小的数

    双指针移动,用st表维护height数组中的最小值。

    当然用单调队列应该也可以且更快。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define N 1010000
    
    using namespace std;
    
    int n, m, t, cnt, len, ans, mx, mn = 1e9;
    int pos[N], a[N / 1000], num[N / 1000], sa[N], height[N], Rank[N], b[N], x[N], y[N], d[N][22], s[N];
    
    inline int read()
    {
    	int x = 0, f = 1;
    	char ch = getchar();
    	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    	return x * f;
    }
    
    inline void build_sa()
    {
    	int i, k, p;
    	for(i = 0; i < m; i++) b[i] = 0;
    	for(i = 0; i < n; i++) b[x[i] = s[i]]++;
    	for(i = 1; i < m; i++) b[i] += b[i - 1];
    	for(i = n - 1; i >= 0; i--) sa[--b[x[i]]] = i;
    	for(k = 1; k <= n; k <<= 1)
    	{
    		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++) b[i] = 0;
    		for(i = 0; i < n; i++) b[x[y[i]]]++;
    		for(i = 1; i < m; i++) b[i] += b[i - 1];
    		for(i = n - 1; i >= 0; i--) sa[--b[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]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p - 1 : p++;
    		if(p >= n) break;
    		m = p;
    	}
    }
    
    inline void build_height()
    {
    	int i, j, k = 0;
    	for(i = 0; 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;
    	}
    }
    
    inline void build_st()
    {
    	int i, j;
    	for(i = 1; i < n; i++) d[i][0] = height[i];
    	for(j = 1; (1 << j) < n; j++)
    		for(i = 1; i + (1 << j) - 1 < n; i++)
    			d[i][j] = min(d[i][j - 1], d[i + (1 << j - 1)][j - 1]);
    }
    
    inline int query(int l, int r)
    {
    	l++;
    	if(l > r) return 0;
    	int tmp = log2(r - l + 1);
    	return min(d[l][tmp], d[r - (1 << tmp) + 1][tmp]);
    }
    
    inline void solve()
    {
    	int i, j = 0;
    	for(i = 0; i < n; i++)
    	{
    		while(j < n && cnt < t)
    		{
    			if(!num[pos[sa[j]]]++ && pos[sa[j]]) cnt++;
    			j++;
    		}
    		if(cnt == t) ans = max(ans, query(i, j - 1));
    		if(!--num[pos[sa[i]]] && pos[sa[i]]) cnt--;
    	}
    }
    
    int main()
    {
    	int i, j, k;
    	t = read();
    	for(i = 1; i <= t; i++)
    	{
    		k = read();
    		for(j = 1; j <= k; j++) a[j] = read();
    		for(j = 1; j < k; j++)
    		{
    			pos[n] = i;
    			s[n++] = a[j + 1] - a[j];
    			mn = min(mn, s[n - 1]);
    		}
    		s[n++] = mx++;
    	}
    	for(i = 0; i < n; i++)
    		if(pos[i]) s[i] = s[i] - mn + mx, m = max(m, s[i]);
    	m++;
    	build_sa();
    	build_height();
    	build_st();
    	solve();
    	printf("%d
    ", ans + 1);
    	return 0;
    }
    

      

  • 相关阅读:
    javaweb学习总结(三十三)——使用JDBC对数据库进行CRUD
    javaweb学习总结(三十二)——JDBC学习入门
    javaweb学习总结(三十一)——国际化(i18n)
    javaweb学习总结(三十)——EL函数库
    javaweb学习总结(二十九)——EL表达式
    javaweb学习总结(二十八)——JSTL标签库之核心标签
    javaweb学习总结(二十七)——jsp简单标签开发案例和打包
    JSP页面中使用JSTL标签出现无法解析问题解决办法
    MySQL客户端输出窗口显示中文乱码问题解决办法
    windows操作系统查看占用端口的进程
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/8286579.html
Copyright © 2011-2022 走看看