The Revenge of the Princess’ Knight

Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

The devil’s birthday is approaching, of course, she wants some beautiful gift from the king. The king search everywhere in this kingdom, and finds a beautiful ring for her.

For simplicity, we can see this ring as a ring(so it is a cycle!) of lowercase characters with length n.

The king’s cute daughter, WJMZBMR, gets nothing from her father in her birthday. She feels very sad. By the influence of the king and the devil, this kingdom is full of lolicon, some people think the king is unfair to his kawayi daughter, so they form a party called princess’s knight and plan to destroy king’s gift for the devil to make things fair.

The knight of the knight (or the lolicon of the lolicon), a man called z*p, has the chance to destroy the ring now. But due to his limitless of strength, he can only cut this ring into exactly k continuous parts. To please the princess, he want among those part, the maximum one respect to the lexicographical order is minimized. How can he do it?

Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains two integers n and k, which are the length of the ring and the parts z*p can cut.
The next line is a string represent the ring.

n <= 1000,1<=k<=n.
T <= 5.

Output
For each case, output the maximum part in one line.
Sample Input
1
20 3
bbbaaaaabbabaabbbbaa
Sample Output
 
aaabbabaabbbbaabbb
Author
WJMZBMR
 
 
【题意】
  字符串环,割成k分,求最大字典序的那个部分最小
 
 
【分析】
  果断是看题解的...

二分的答案就是这K个块字典序的上限。假设以i作为起点,由于字典序上限已知,所以我们可以立刻求出i点最远能选到哪个点。

现在问题变成了:已知每一个点最远能跳R的距离,求是否存在一条路径,使得跳K次回到起点。

首先我们假设,每个点的R≠0,意思就是每个点都能向后跳,这样我们只需要用贪心的思想,枚举任意点为起点,然后向后能跳多少跳多少,若跳回来所花的次数T<=K,则为true 【由于每个点都能向后跳,则我们一定能够通过改变几个跳跃,使得T==K  若当前的点数<K,也就是每次只跳1步都没法跳到,当然就是false了】

现在的问题就是,如果有某些点R==0怎么办,也就是它一步也不能向后跳,并且其它位置也不能跳到这个位置。所以我们想到,将这个点删除掉,并且,将所有受到影响的点全部减一,以前可以从 a向后跳3步,但现在 b (a<=b<=a+3)被删掉了,所以a只能挑2步了,这样最多迭代n次 处理之后,所有点的R都是不为0的了。

http://blog.csdn.net/t1019256391/article/details/38347293

  对于删点那部分操作呢。我是从后往前扫,要是它要跳到一个为0的点,那么它的skip就变成离这个为0的点最接近的不为0的点。

for(int i=q;i<=q+n-1;i++) nr[i]=0;
for(int i=q+n-1;i>=q;i--)
{
if(sk[i]>0&&sk[i]!=q+n)
{
if(sk[sk[i]]==0&&nr[sk[i]]==0) sk[i]=0,h--;
else if(sk[sk[i]]==0) sk[i]=nr[sk[i]];
}
if(sk[i]>0)
{
for(int j=i+1;j<=q+n-1;j++)
{
if(sk[j]>0) break;
nr[j]=i;
}
}
}

  所以删点是O(n)的,我二分完之后还每次枚举开始的位置(我自己感觉不枚举会丧失单调性啊。。好像)

  然后还有一个二分咯,总时间复杂度是O(n^2 logn)

  可以说我还没AC么。。拍了一个上午了。。

.

.

.

.

.

.

  好吧现在我A了。。。对拍没用啊!!还是自己Y出的错。。

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 4010
#define INF 0xfffffff char s[Maxn];
int n,c[Maxn],cl,k; void init()
{
scanf("%s",s+);
cl=;
for(int i=;i<=n;i++) c[++cl]=s[i]-'A'+;
for(int i=;i<=n;i++) c[++cl]=s[i]-'A'+;
} int mymin(int x,int y) {return x<y?x:y;} int rk[Maxn],sa[Maxn],Rs[Maxn],y[Maxn],wr[Maxn];
void get_sa(int m)
{
memcpy(rk,c,sizeof(rk));
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[rk[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i; int p=,ln=;
while(p<cl)
{
int kk=;
for(int i=cl-ln+;i<=cl;i++) y[++kk]=i;
for(int i=;i<=cl;i++) if(sa[i]>ln) y[++kk]=sa[i]-ln;
for(int i=;i<=cl;i++) wr[i]=rk[y[i]]; for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[wr[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=;i<=cl;i++) wr[i]=rk[i];
for(int i=cl+;i<=cl+ln;i++) wr[i]=;
p=,rk[sa[]]=;
for(int i=;i<=cl;i++)
{
if(wr[sa[i]]!=wr[sa[i-]]||wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
rk[sa[i]]=p;
}
m=p,ln*=;
}
sa[]=rk[]=;
} int height[Maxn];
void get_he()
{
int kk=;
for(int i=;i<=cl;i++) if(rk[i]!=)
{
int j=sa[rk[i]-];
if(kk) kk--;
while(c[i+kk]==c[j+kk]&&i+kk<=cl&&j+kk<=cl) kk++;
height[rk[i]]=kk;
}
height[]=;
} int lcp[][]; void get_lcp()
{
for(int i=;i<=cl;i++)
{
int minn=INF;
for(int j=i+;j<=cl;j++)
{
minn=mymin(minn,height[j]);
lcp[sa[i]][sa[j]]=lcp[sa[j]][sa[i]]=minn;
}
}
for(int i=;i<=cl;i++) lcp[i][i]=cl-i+;
} int sk[Maxn],nr[Maxn];
bool check(int x,int l)
{
for(int q=;q<=n;q++)
{
int h=n;
for(int i=q;i<=q+n-;i++)
{
if(lcp[i][sa[x]]==&&c[i]>c[sa[x]]) {h--;sk[i]=;continue;} if(lcp[i][sa[x]]>=l) sk[i]=i+l;
else if(c[i+lcp[i][sa[x]]]>c[sa[x]+lcp[i][sa[x]]]) sk[i]=i+lcp[i][sa[x]];
else sk[i]=q+n; if(sk[i]>q+n) sk[i]=q+n;
} for(int i=q;i<=q+n-;i++) nr[i]=;
for(int i=q+n-;i>=q;i--)
{
if(sk[i]>&&sk[i]!=q+n)
{
if(sk[sk[i]]==&&nr[sk[i]]==) sk[i]=,h--;
else if(sk[sk[i]]==) sk[i]=nr[sk[i]];
}
if(sk[i]>)
{
for(int j=i+;j<=q+n-;j++)
{
if(sk[j]>) break;
nr[j]=i;
}
}
} if(h<k||sk[q]==) continue; int now=q;h=;
while(now<q+n)
{
now=sk[now];
h++;
}
if(h<=k) return ;
}
return ;
} int fffind(int x)
{
int l,r;bool ok=;
l=;
r=mymin(n,cl-sa[x]+);
while(l<r)
{
int mid=(l+r)>>;
if(check(x,mid)) r=mid,ok=;
else l=mid+;
}
if(check(x,l)) ok=;
if(!ok) return -;
return l;
} int eg[Maxn]; void ffind()
{
int l,r,h=;
for(int i=;i<=cl;i++) if(sa[i]<=n) eg[++h]=i;
l=;r=h;
while(l<r)
{
int mid=(l+r)>>;
if(fffind(eg[mid])!=-) r=mid;
else l=mid+;
}
int x=fffind(eg[l]);
for(int i=sa[eg[l]];i<=sa[eg[l]]+x-;i++) printf("%c",c[i]-+'A');
printf("\n");
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
init();
get_sa();
get_he();
get_lcp();
ffind();
}
return ;
}

[HDU4898]

  

2016-08-26 14:30:59

【HDU 4898】 The Revenge of the Princess’ Knight (后缀数组+二分+贪心+...)的更多相关文章

  1. hdu 4898 The Revenge of the Princess’ Knight

    传送阵:http://acm.hdu.edu.cn/showproblem.php?pid=4898 题目大意:一个首尾相连的字符串,将其分为k个子串,使得最大的字串最小 将所有子串排序,输出第k小即 ...

  2. HDU 4898 The Revenge of the Princess’ Knight(后缀数组+二分+暴力)(2014 Multi-University Training Contest 4)

    Problem Description There is an old country and the king fell in love with a devil. The devil always ...

  3. HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )

    题意:给定一个环形字符串,让他把它分成k份,使得最大的字典序 最小. 思路:二分答案,首先很明显答案所有可能是 n*n种  排序可以先求出最长公共前缀,这样比较就只需要比较公共前缀的下一位就能比较出两 ...

  4. HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  5. HDU 5008 Boring String Problem(后缀数组+二分)

    题目链接 思路 想到了,但是木写对啊....代码 各种bug,写的乱死了.... 输出最靠前的,比较折腾... #include <cstdio> #include <cstring ...

  6. HDU 5558 后缀数组+二分

    题意有一些绕,但其实就是对于不断变化的i,求以j(0=j<i)使得suffix[j]与suffix[i]的最长公共前缀最长,如果有多个j,则取最小的j. 可以在rank数组中二分,在1-rank ...

  7. hdu 6194 沈阳网络赛--string string string(后缀数组)

    题目链接 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle M ...

  8. HDU 3948 The Number of Palindromes(Manacher+后缀数组)

    题意 求一个字符串中本质不同的回文子串的个数. $ 1\leq |string| \leq 100000$ 思路 好像是回文自动机的裸题,但是可以用 \(\text{Manacher}\) (马拉车) ...

  9. HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)

    好题 题意:给你n<=100000个数,每个数范围[0,1000],然后给你一个最大的代价T,每次最多合并k个数成为一个数,代价为k个数的总和.问最后合成1个数的总代价不大于T的最小k 题解:我 ...

随机推荐

  1. 在AngularJS的controller外部直接获取$scope

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/5560843.html ...

  2. 第十一篇:web之Django之Form组件

    Django之Form组件   Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功 ...

  3. Unity3D 3D坦克大战

    视频学习来源 移动和旋转 using UnityEngine; using System.Collections; /* * Adminer:sun2955 * http:www.yinghy.com ...

  4. asp.net 开发问题:Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值。

    "Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值." 这个问题在开发需要上传文件的时候可能会遇到,今天遇到这个问题,百度过也有挺多的修改方法. 方法1: 修 ...

  5. java中数据类型及运算符的注意事项

    数据类型: boolean 类型数据只允许取值true 或 false(不可以使用0 或非0的整数来代替true和false,区分于C语言). char:Java中用" \u四位十六进制的数 ...

  6. SQLServer2012分离出的数据库存放路径

    分离出的数据库没有保存位置提示,经常会导致分离出的数据库找不到  以下是分离出的数据库默认位置: C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQL ...

  7. IOS 高级开发 runtime(二)

    二.移魂大法 使用runtime还可以交换两个函数.先贴上代码和执行结果. #import <Foundation/Foundation.h> @interface DZLPerson : ...

  8. ASP.NET中的验证控件

    ASP.NET提供了如下的控件: RequiredFieldValidator: 字段必填 (ControlTovalidate设定要验证的控件) RangeValidator: 值在给定的最大值,最 ...

  9. 《tr命令-优化版》-linux命令五分钟系列之二十五

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  10. webstorm快捷方式

    刚开始在使用webstrom的时候,不知道快捷方式,感觉自己把webstorm当做记事本使用,真的挺傻的,在朋友的指导下,原来webstorm有快捷方式 一.界面操作 快捷键 说明 ctrl+shif ...