https://konnyakuxzy.github.io/BZPRO/JudgeOnline/2740.html

题解讲的很清楚了

(好像等于的情况应该归入case2而不是case1?并不确定)

具体方法:

将串翻转,找到字典序最小且最短的后缀,然后找到以这个后缀为纯循环节的最长后缀T,则第一步是将这个后缀T提到最前面;

然后第二步是把整个串除T外部分变为其循环同构串的最小表示。

要找到字典序最小且最短的后缀,只要找到整个串的最小表示法(设最小表示法在位置i开始),然后找到S[i..n]的最短公共前后缀即可(容易发现是对的)(见代码1);也可以直接用最小表示法类似的方法一次直接求出来(见代码2)

代码1:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii; int T;
char s[];
int f[];
int calc(const char *s,int n)
{
int i=,j=,k=,t;
while(i<n&&j<n&&k<n)
{
t=s[(i+k)%n]-s[(j+k)%n];
if(t==) ++k;
else
{
if(t>) i+=k+;
else j+=k+;
if(i==j) ++j;
k=;
}
}
return min(i,j);
}
int n;
int an1,an2;
int main()
{
int i,j,t;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);n=strlen(s);
reverse(s,s+n);
t=calc(s,n);
//printf("1t%d\n",t);
//t=0;
f[t]=;
for(i=t+,j=;i<n;++i)
{
//j=f[i-1];
while(j>&&s[t+j]!=s[i]) j=f[t+j-];
//printf("2t%d %c %c\n",j,s[t+j],s[i]);
if(s[t+j]==s[i]) ++j;
//printf("1t%d %d %d\n",i,t+j,s[t+j]==s[i]);
f[i]=j;
}
//for(i=t;i<n;++i) printf("%d %d\n",i,f[i]);
j=f[n-];
if(j)
{
while(f[t+j-]>) j=f[t+j-];
t=n-j;
}
//printf("1t%d\n",t);
for(j=t;;)
{
//printf("3t%d %d\n",j-(n-t),t);
if(j>=n-t&&strncmp(s+(j-(n-t)),s+t,n-t)==)
j-=n-t;
else
break;
}
t=j;
//printf("2t%d\n",t);
an1=n-t;
//printf("%d\n",an1);
//printf("%d\n",t);
t=calc(s,t);
an2=n-t;
printf("%d %d\n",an1,an2);
}
return ;
}

代码2:(话说这个复杂度真的对吗?不确定啊?不过实测全a串还有一些随机的串的确是O(n)的,并且能A掉题)

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
int T;
char s[];
//int f[10000100];
int calc(const char *s,int n)
{
int i=,j=,k=,t;
while(i<n&&j<n&&k<n)
{
t=s[(i+k)%n]-s[(j+k)%n];
if(t==) ++k;
else
{
if(t>) i+=k+;
else j+=k+;
if(i==j) ++j;
k=;
}
}
return min(i,j);
}
int n;
int an1,an2;
int main()
{
int i,j,k,t;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
n=strlen(s);
reverse(s,s+n);
i=;j=;k=;
//int tt=0;
while(i<n&&j<n&&k<n)
{
//++tt;
//printf("1t%d %d %d\n",i,j,k);
t=((i+k<n)?s[i+k]:)-((j+k<n)?s[j+k]:);
if(t==) ++k;
else
{
if(t>) i+=(j+k<n)?k+:k;
else j+=(i+k<n)?k+:k;
if(i==j) ++j;
k=;
}
}
//printf("1t%d\n",tt);
t=min(i,j);
for(j=t;;)
{
if(j>=n-t&&strncmp(s+(j-(n-t)),s+t,n-t)==)
j-=n-t;
else
break;
}
t=j;
an1=n-t;
t=calc(s,t);
an2=n-t;
printf("%d %d\n",an1,an2);
}
return ;
}

https://konnyakuxzy.github.io/BZPRO/JudgeOnline/2176.html

最小表示法板子

题解

这题数据范围比较诡异,一定要用unsigned char。。。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
unsigned char s[];
int calc(const unsigned char *s,int n)
{
int i=,j=,k=,t;
while(i<n&&j<n&&k<n)
{
t=s[(i+k)%n]-s[(j+k)%n];
if(t==) ++k;
else
{
if(t>) i+=k+;
else j+=k+;
if(i==j) ++j;
k=;
}
}
return min(i,j);
}
int n;
int main()
{
int t;
scanf("%d%s",&n,s);
t=calc(s,n);
printf("%s",s+t);
s[t]=;
printf("%s",s);
return ;
}

bzoj2740 串 && bzoj2176 strange string(最小表示法模板)的更多相关文章

  1. BZOJ 2176 Strange string 最小表示法

    题目大意:给定一个串S,求最小表示法 n<=1000W,实在不敢写后缀自己主动机,就去学了最小表示法= = 记得用unsigned char不然WA= = 数据真是逗- - #include & ...

  2. BZOJ 2176 Strange string ——最小表示法

    本来想用来练习后缀自动机的,但是100w有点虚(事实证明确实T掉了). 只好上最小表示法. #include <cstdio> #include <cstring> #incl ...

  3. BZOJ2176Strange string——最小表示法

    题目描述 给定一个字符串S = {S1, S2, S3 … Sn}, 如果在串SS中, 子串T(|T| = n)为所有长度为n的SS的字串中最小的(字符串的比较), 则称T为”奇怪的字串”. 你的任务 ...

  4. Manacher模板,kmp,扩展kmp,最小表示法模板

    *N]; //储存临时串 *N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); ; ;i<len;i++) { s[cnt++]= ...

  5. bzoj2176 Strange string(字符串最小表示法)

    Time Limit: 10 Sec  Memory Limit: 259 MB 给定一个字符串S = {S1, S2, S3 … Sn}, 如果在串SS中, 子串T(|T| = n)为所有长度为n的 ...

  6. HDU3374 字符串最大最小表示法模板

    一开始没太看懂什么意思,拿笔反复推了一遍才大概知道最大最小表示法是怎么求的,感觉太神奇了... #include <iostream> #include <cstdio> #i ...

  7. 最小标示法模板 poj1509

    最小标示法:给定一个字符串,不断将其最后一个字符放到开头,最终会得到n个字符串,称这n个字符串循环同构,这些字符串中字典序最小的一个,就是最小表示法 #include<iostream> ...

  8. [USACO5.5]隐藏口令Hidden Password [最小表示法模板]

    最小表示法就是一个字符串构成一个环,找以哪个点为开头字典序最小. 然后我们就可以用n2的算法愉快的做啦~实际上有O(n)的做法的,就是用两个指针扫,如果这两个位置的字典序相等,就一起往后,如果某一个大 ...

  9. HDU - 3374:String Problem (最小表示法模板题)

    Give you a string with length N, you can generate N strings by left shifts. For example let consider ...

随机推荐

  1. 微信 jssdk 逻辑在 vue 中的运用

    微信 jssdk 在 vue 中的简单使用 import wx from 'weixin-js-sdk'; wx.config({ debug: true, appId: '', timestamp: ...

  2. HDU4965 Fast Matrix Calculation —— 矩阵乘法、快速幂

    题目链接:https://vjudge.net/problem/HDU-4965 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Othe ...

  3. HDU4990 Reading comprehension —— 递推、矩阵快速幂

    题目链接:https://vjudge.net/problem/HDU-4990 Reading comprehension Time Limit: 2000/1000 MS (Java/Others ...

  4. TCP连接过程

    TCP建立连接与释放连接  最近复习准备<计算机网络>考试,感觉TCP协议建立连接与释放连接这两个过程比较重要,所以把自己理解的部分写下来. 1.建立连接:(三次握手)   (1)客户端发 ...

  5. 004-画图神器-graphviz

    1 安装及基本使用 1) 下载安装 下载地址 可以下载安装版进行安装或者解压版直接使用 2) 添加系统path 为了能够在dos中使用命令, 需要添加环境变量 默认安装路径为 C:\Program F ...

  6. spring boot 部署 发布

    Spring Boot应用的打包和部署 字数639 阅读2308 评论0 喜欢5 现在的IT开发,DevOps渐渐获得技术管理人员支持.云计算从ECS转向Docker容器技术.微服务的概念和讨论也越来 ...

  7. AngularJS系统学习之Factory,Service, Provider(工厂,服务,供应者)

    本文转自:http://blog.csdn.net/zcl_love_wx/article/details/51404390 我看过敲过代码之后, 有了很深的理解, 这三个东西其实都是用来返回对象的. ...

  8. linux内核中ip,tcp等头的定义(转)

    一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/typedef struct _MAC_FRAME_HEADER{ char m_cDstMacAddress[6];    //目的m ...

  9. 【Linux学习】Linux文件系统6—文件目录权限设置

    Linux文件系统6-文件目录权限设置 1.       chmod操作权限设置 chomd是用来改变文件或目录权限的命令,但只有文件的属主和超级权限用户root才有这种权限.通过chmod来改变文件 ...

  10. 微信小程序开发之页面跳转并携带参数

    接口: wx.navigateTo({url:......})   保留当前页面,跳转到应用内指定URL页面,导航栏左上角有返回按钮 wx.redirecTo({url:.....})       关 ...