【bzoj4486】【JSOI2015】串分割
老省选题了。
首先考虑怎么比较超长数字的大小?
参见UTR1的那道题
先比size,然后比较字典序即可。
接下来考虑下切割的问题。
因为要将字符串切割成k份,所以这个字符串只会存在n/k个本质不同的起始位置。
然后可能会发现,如果能够整除的话,将这些起始位置直接后缀排序就可以了。
那么如果不能整除怎么办?
我们可以发现,如果有多余的,那么最长的字符串一定最多比别人多1
这个贪心的正确性比较的显然。
那么我们怎么处理长度不同的呢?
将之前的比较二分即可。
- #include<bits/stdc++.h>
- #define N 400010
- using namespace std;
- int t1[N],t2[N],a[N],sa[N],rk[N],c[],h[N];
- int n,m,k,cnt;
- char s[N];
- void calcsa(int n,int m){
- int *x=t1,*y=t2,f=,p=;
- for(int i=;i<=m;i++)c[i]=;
- for(int i=;i<=n;i++)c[x[i]=a[i]]++;
- for(int i=;i<=m;i++)c[i]+=c[i-];
- for(int i=n;i;i--)sa[c[x[i]]--]=i;
- for(int i=;i<=n&&p<=n;i<<=){p=;
- for(int j=n-i+;j<=n;j++)y[++p]=j;
- for(int j=;j<=n;j++)if(sa[j]>i)y[++p]=sa[j]-i;
- for(int j=;j<=m;j++)c[j]=;
- for(int j=;j<=n;j++)c[x[y[j]]]++;
- for(int j=;j<=m;j++)c[j]+=c[j-];
- for(int j=n;j>=;j--)sa[c[x[y[j]]]--]=y[j];
- swap(x,y);x[sa[]]=;p=;
- for(int j=;j<=n;j++)
- x[sa[j]]=y[sa[j]]==y[sa[j-]]&&y[sa[j]+i]==y[sa[j-]+i]?p-:p++;
- m=p;
- }
- for(int i=;i<=n;i++)rk[sa[i]]=i;
- for(int i=;i<=n;i++){
- int j=sa[rk[i]-];
- if(f)f--;while(a[i+f]==a[j+f])f++;
- h[rk[i]]=f;
- }
- }
- inline bool check(int x){
- int p;
- for(int i=;i<=m;i++){
- int t=i;p=k;
- while(p--){
- if(rk[t]<=x)t+=m;else t+=m-;
- if(t>=n+i)return ;
- }
- }
- return ;
- }
- inline void work(){
- int l=,r=cnt;
- while(l<r){
- int mid=(l+r)>>;
- if(check(mid))r=mid;else l=mid+;
- }
- for(int i=;i<=n;i++)if(rk[i]==l)
- for(int j=i;j<=i+m-;j++)printf("%c",a[j]+'');
- puts("");
- }
- int main(){
- scanf("%d%d",&n,&k);scanf("%s",s+);
- for(int i=;i<=n;i++)a[++cnt]=s[i]-'';
- for(int i=;i<n;i++)a[++cnt]=s[i]-'';
- calcsa(cnt,);
- //for(int i=1;i<=cnt;i++)printf("%d ",sa[i]);puts("");
- m=n/k+(n%k!=);
- work();
- }
【bzoj4486】【JSOI2015】串分割的更多相关文章
- bzoj4486: [Jsoi2015]串分割
肉丝哥哥钦定好题 话说我的blog现在为什么到处都是肉丝哥哥 先来想一个弱化版,假如能够n整除K怎么做? 把每个数字看成一个字符串,按字典序排名,这个可以后缀数组解决,然后暴力枚举每种情况,O(1)判 ...
- 「JSOI2015」串分割
「JSOI2015」串分割 传送门 首先我们会有一个贪心的想法:分得越均匀越好,因为长的绝对比短的大. 那么对于最均匀的情况,也就是 \(k | n\) 的情况,我们肯定是通过枚举第一次分割的位置,然 ...
- C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出
C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出 strstr() 命令是在原字符串中查找指定的字符串第一次出现的地址,用这个特性可以实现字符的分割,判断是否包涵等功能: ...
- Minimum Palindromic Factorization(最少回文串分割)
Minimum Palindromic Factorization(最少回文串分割) 以下内容大部分(可以说除了关于回文树的部分)来自论文A Subquadratic Algorithm for Mi ...
- Java开发笔记(三十七)利用正则串分割字符串
前面介绍了处理字符串的常用方法,还有一种分割字符串的场景也很常见,也就是按照某个规则将字符串切割为若干子串.分割规则通常是指定某个分隔符,根据字符串内部的分隔符将字符串进行分割,例如逗号.空格等等都可 ...
- Codeforces 898 贪心关闭最少闹钟 优先队列最少操作构造N/2squares 讨论情况哈希数字串分割a+b=c
A /* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- SAM 做题笔记(各种技巧,持续更新,SA)
SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...
随机推荐
- 2016 China Final E - Bet
/************************************************************************* > File Name: E.cpp > ...
- [洛谷P3878][TJOI2010]分金币
题目大意:把$n(n\leqslant30)$个数分成两组,两组个数最多相差$1$,求出两组元素差的绝对值最小使多少 题解:模拟退火 卡点:$\exp$中的两个数相减写反,导致$\exp(x)$中的$ ...
- CF311B Cats Transport 斜率优化DP
题面:CF311B Cats Transport 题解: 首先我们观察到山与距离其实是没有什么用的,因为对于任意一只猫,我们都可以直接算出如果有一个人要恰好接走它,需要在哪一时刻出发,我们设第i只猫对 ...
- [CQOI2012]交换棋子 网络流
---题面--- 题解: 一开始很快想出了一个接近正解的建图方法,但其实是错误的,不过还是骗了70分_(:зゝ∠)_ 首先我们可以观察到棋子有限,但费用多种,其实也就相当于限制了流量,找最小费用 对于 ...
- ural1297 求最长回文子串 | 后缀数组
#include<cstdio> #include<algorithm> #include<cstring> #define N 20005 using names ...
- Jsp电子商务之七 订单篇2
从View页面,点击超链接查询订单,进入到控制器 OrderlistServlet package com.cart.web; import java.io.IOException; import j ...
- 被引用的外部JS存在window.onload时,判断当前页面是否已存在window.onload,并进行相应处理
如果页面a.html引用了b.js,b.js里的方法需要在页面资源加载完成后执行,即在window.onload里执行:这时如果a.html里使用了window.onload方法,b.js就不能重复调 ...
- HDU 3507 斜率优化dp
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- mysql的时间函数整理
转:这里总结的非常齐全: http://fengbin2005.iteye.com/blog/1999763 Mysql时间函数 对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描 ...
- Leetcode 485. 最大连续1的个数
1.题目描述(简单题) 给定一个二进制数组, 计算其中最大连续1的个数. 示例 1: 输入: [1,1,0,1,1,1] 输出: 3 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 ...