zoukankan      html  css  js  c++  java
  • 【Luogu P2870】[USACO07DEC]Best Cow Line G

    链接:

    洛谷

    题目大意:

    给定一个串,每次选择最前或最后的字符,求最后能得到字典序最小的串。

    正文:

    贪心时遇到 ( exttt{BACB}) 这样的串时,不能随便选,于是想到了后缀数组。那么取最后的字符,就相当于把原串反过来。所以先对原串如此处理:(S'=S+ exttt{@}+ar{S}),其中 ( exttt{@}) 表示特殊符号,(ar{S}) 表示 (S) 翻转后的串。

    代码:

    const int N = 2e6 + 10;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    int n, m = 122;
    int sa[N], x[N], y[N], c[N];
    char s[N];
    
    void SA()
    {
    	for (int i = 1; i <= m; i++) c[i] = 0;
    	for (int i = 1; i <= n; i++) c[x[i] = s[i]]++;
    	for (int i = 2; i <= m; i++) c[i] += c[i - 1];
    	for (int i = n; i; i--) sa[c[x[i]]--] = i;
    	
    	for (int k = 1; k <= n; k <<= 1)
    	{
    		int num = 0;
    		for (int i = n - k + 1; i <= n; i ++) y[++num] = i;
    		for (int i = 1; i <= n; i++)
    			if (sa[i] > k) y[++num] = sa[i] - k;
    		
    		for (int i = 1; i <= m; i++) c[i] = 0;
    		for (int i = 1; i <= n; i++) c[x[i]]++;
    		for (int i = 2; i <= m; i++) c[i] += c[i - 1];
    		for (int i = n; i; i--) sa[c[x[y[i]]]--] = y[i], y[i] = 0;
    		
    		swap (x, y);
    		x[sa[1]] = 1, num = 1;
    		for (int i = 2; 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;
    		if (n == m) break;
    	}
    	return ;
    }
    
    int main()
    {
    //	freopen(".in", "r", stdin);
    //	freopen(".out", "w", stdout);
    	int k = Read();
    	for (int i = 1; i <= k; i++) 
    	{
    		char c = getchar();
    		while (c < 'A' || c > 'Z') c = getchar();
    		s[i] = c;
    	}
    	n = k << 1 | 1;
    	for (int i = 1; i <= k; i++) s[k + 1 + i] = s[k - i + 1];
    	s[k + 1] = 'Z' + 1;
    	SA();
    	for (int i = 1, j = k, tot = 1; i <= j; tot++)
    	{
    		if (x[i] < x[n - j + 1]) putchar(s[i++]);
    		else putchar(s[j--]);
    		if (!(tot % 80)) putchar(10);
    	}
    	return 0;
    }
    
  • 相关阅读:
    ObjectiveC分类
    显示时间格式
    js模拟签名
    安装卸载homebrew
    NSFastEnumeration
    拼接音频
    在Orchard模块中访问模块本地的AppSettings
    重装证书
    msysgit中文问题
    Apple Push Notification service
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/15430432.html
Copyright © 2011-2022 走看看