http://1572m36l09.iask.in:30808/problem/31

首先转化为保留尽量少的段使得字典序最大。考虑逐字符确定,
显然我们可以将相同的连续字符缩在一起。注意到字典序最大的
字符一定会在前缀中保留尽量多次,我们可以将字符相同的连续
段按照出现次数排序,并逐一确定。在确定最后一段时,我们需
要考虑剩余部分后缀对串的大小的影响。使用后缀数组处理,时
间复杂度为 O(|s| log |s|)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
;
struct node
{
    int l,r;
}a[N];
vector<node> vct[];
int t,K,n,m,i,j,k,l,x,y,sa[N],rk[N],Y[N],c[N],len;
char s[N],ans[N];
bool cmp(node a,node b)
{
    return a.l<b.l;
}
bool cmq(node a,node b)
{
    if(a.r-a.l!=b.r-b.l)
        return a.r-a.l>b.r-b.l;
    return a.l<b.l;
}
void add(char c,int x)
{
    while(x--)
        ans[++len]=c;
}
int main()
{
    freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    scanf("%d",&t);
    while(t--)
    {
        scanf();
        )//注意K==0时要特判
        {
            puts(s+);
            continue;
        }
        n=strlen(s+);
        m=;
        len=;
        ;i<=n;++i)
            rk[i]=s[i];
        ;i<=m;++i)
            c[i]=;
        ;i<=n;++i)
            c[rk[i]]++;
        ;i<=m;++i)
            c[i]+=c[i-];
        ;i<=n;++i)
            sa[c[rk[i]]--]=i;
        ;k<=n;k<<=)
        {
            ,l=;i<=n;++i)
                Y[++l]=i;
            ;i<=n;++i)
                if(sa[i]>k)
                    Y[++l]=sa[i]-k;
            ;i<=m;++i)
                c[i]=;
            ;i<=n;++i)
                c[rk[i]]++;
            ;i<=m;++i)
                c[i]+=c[i-];
            ;--i)
                sa[c[rk[Y[i]]]--]=Y[i];
            ;i<=n;++i)
                Y[i]=rk[i];
            rk[sa[]]=m=;
            ;i<=n;++i)
                rk[sa[i]]=(Y[sa[i]]==Y[sa[i-]]&&(sa[i]+k>n?:Y[sa[i]+k])==(sa[i-]+k>n?:Y[sa[i-]+k])?m:++m);
            if(rk[sa[n]]==n)//SA的一个优化
                break;
        }
        rk[n+]=;//注意细节!!
        ;i<;++i)
            vct[i].clear();
        ;i<=n;i=j)
        {
            for(j=i;j<=n&&s[i]==s[j];++j);
            vct[s[i]-});
        }
        ,j=k=;i>=;--i)
        {
            l=vct[i].size();
            if(!l)
                continue;
            sort(vct[i].begin(),vct[i].end(),cmp);
            ;x<l&&vct[i][x].l<=j;++x);
            if(x>=l)
                continue;
            )
            {
                add(i+);
                j=vct[i][x++].r;
            }
            if(l-x+k<K)
            {
                j=vct[i][l-].r;
                k+=l-x;
                for(;x<l;++x)
                    add(i+);
                continue;
            }
            sort(vct[i].begin()+x,vct[i].end(),cmq);
            ;++x)
            {
                add(i+);
                ++k;
                j=max(j,vct[i][x].r);
            }
            k=vct[i][x].r-vct[i][x].l+;
            add(i+'a',k);
            ;x<l&&vct[i][x].r-vct[i][x].l+==k;++x)
                ||rk[max(j+,vct[i][x].r+)]>rk[y])
                    y=max(j+,vct[i][x].r+);
            for(;y<=n;++y)
                add(s[y],);
            j=n;
            break;
        }
        ans[len+]=;
        puts(ans+);
    }
    ;
}

FZOJβ #31.字符串的更多相关文章

  1. 31:字符串p型编码

    31:字符串p型编码 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个完全由数字字符('0','1','2',…,'9')构成的字符串str,请写出s ...

  2. AC日记——字符串P型编码 openjudge 1.7 31

    31:字符串p型编码 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个完全由数字字符('0','1','2',…,'9')构成的字符串str,请写出str的p型编码串.例如: ...

  3. NOI 1.7编程基础之字符串(35题)

    01:统计数字字符个数 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一行字符,统计出其中数字字符的个数. 输入 一行字符串,总长度不超过255. 输出 ...

  4. Python之字符串的特性及常用方法

    字符串的特性 索引: (索引是从0开始) s='hello'print(s[0])print(s[4])print(s[-1]) #拿出最后一个字符 hoo12345678截取s[start:stop ...

  5. Python基础教程之第3章 使用字符串

    Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "copyri ...

  6. [转]Python程序员必须知道的30条编程技巧

    30 tips & tricks for Python Programming 1  直接交换两个数字位置 x, y = 10, 20 print(x, y) x, y = y, x prin ...

  7. Swift:网络库Alamofire

    一,Alamofire的说明与配置 1,什么是Alamofire (1)Alamofire 的前身是 AFNetworking.AFNetworking 是 iOS 和 OS X 上很受欢迎的第三方H ...

  8. QJ系列笔记

    1.求int型数据在内存中存储时1的个数输入一个int型数据,计算出该int型数据在内存中存储时1的个数. #include<stdio.h> void main() { ; int yu ...

  9. 如何实现在Windows上运行Linux程序,附示例代码

    微软在去年发布了Bash On Windows, 这项技术允许在Windows上运行Linux程序, 我相信已经有很多文章解释过Bash On Windows的原理, 而今天的这篇文章将会讲解如何自己 ...

随机推荐

  1. 剑指Offer的学习笔记(C#篇)-- 对称的二叉树

    题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 一 . 题目分析 递归法. 一.空树判断,单独搞出来. 二.非空树. 递归:一 ...

  2. Request a certificate from a certificate vendor

    Request a certificate from a certificate vendor Now, with your CSR in hand, visit the Web site of yo ...

  3. Oracle树查询总结

    最近在做公司的项目中遇到一个问题,多级级联导航菜单,虽然只有三级目录,但<li>中嵌套<ul>,数据库表结构如下: CREATE TABLE FLFL ( ID NUMBER ...

  4. 笔记-JavaWeb学习之旅15

    Filter:过滤器 概念:当访问服务器的资源是,过滤器可以将请求拦截下来,完成一些特殊的功能 快速入门: 步骤: 定义一个类,实现接口Filter 复写方法 配置拦截路径 package com.d ...

  5. Mac下通过homebrew安装maven

    1.安装Homebrew 将以下命令粘贴至终端 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebr ...

  6. Continuous Integration

    https://dzone.com/articles/continuous-delivery-toolchain

  7. 关于java多线程任务执行时共享资源加锁的方式思考

    1.加锁方式: 1-1.使用synchronized关键字进行方法或代码块的加锁方式 1-2.使用ReentrantLock类提供的lock()方法的方式 2.代码实现(传统的银行取款存款问题): 2 ...

  8. python中cursor操作数据库(转)

    原文出处:http://doudouclever.blog.163.com/blog/static/175112310201284115340663/ python 操作数据库,要安装一个Python ...

  9. Datagridview强制结束编辑状态

    DirectCast(dgvTab1.CurrentRow.DataBoundItem, DataRowView).EndEdit() dgvTab1.CommitEdit(DataGridViewD ...

  10. csrf攻击实例

    CSRF 攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在并未授权的情况下执行在权限保护之下的操作.比如说,受害者 Bob 在银行有一笔存款,通过对银行的网站发送请求 ht ...