BZOJ 1398: Vijos1382寻找主人 Necklace(最小表示法)
解题思路
最小表示法。首先对于判断是不是循环同构的串,直接扫一遍用哈希判即可。然后要输出字典序最小的就要用到最小表示法,首先可以把串复制一遍,这样的话就可以把串变成静态操作。如果对于两个位置\(i,j\),若他们\(i\sim i+k-1\)与\(j\sim j+k-1\)这些位置都两两相等,而\(s[i+k]<s[j+k]\)的话。那么首先可以知道的是\(j\)这个位置一定不是最小表示的开头,还有一个性质就是\(j\sim j+k\)这些位置也一定不是,因为\(s[i+k]<s[j+k]\),那么这些位置也一定有一个对应的\(i_0\),使得他们在\(i+k\)的位置依然不相等。所以用一个双指针扫,时间复杂度\(O(n)\)。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
const int MAXN = 1000005;
const int base = 666623333;
typedef unsigned long long ULL;
char s1[MAXN],s2[MAXN];
ULL hsh1[MAXN<<1],hsh2[MAXN],poww[MAXN<<1];
int ans,n;
bool flag;
inline bool check(int x){
return (hsh1[x+n-1]-hsh1[x-1]*poww[n])==(hsh2[n]-poww[n])?1:0;
}
int main(){
scanf("%s%s",s1+1,s2+1);
n=strlen(s1+1);
for(int i=1;i<=n;i++) s1[i+n]=s1[i];hsh1[0]=hsh2[0]=1;poww[0]=1;
for(int i=1;i<=(n<<1);i++) {hsh1[i]=hsh1[i-1]*base+s1[i]-'0'+1;poww[i]=poww[i-1]*base;}
for(int i=1;i<=n;i++) hsh2[i]=hsh2[i-1]*base+s2[i]-'0'+1;
for(int i=1;i<=n;i++) if(check(i)) {flag=1;break;}
if(!flag) {puts("No");return 0;}
puts("Yes");int l=1,r=2,k;
while(l<=n && r<=n) {
for(k=0;s1[l+k]==s1[r+k] && k<=n;k++);
if(k==n) break;
if(s1[l+k]<s1[r+k]) {r=r+k+1;r+=(r==l);}
else {l=l+k+1;l+=(l==r);}
}
ans=min(l,r);
for(int i=ans;i<=ans+n-1;i++) putchar(s1[i]);putchar('\n');
return 0;
}
BZOJ 1398: Vijos1382寻找主人 Necklace(最小表示法)的更多相关文章
- [bzoj 1398] Vijos1382寻找主人 Necklace 解题报告(最小表示法)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1398 题目: Description 给定两个项链的表示,判断他们是否可能是一条项链. ...
- 【BZOJ 1398】 1398: Vijos1382寻找主人 Necklace (最小表示法)
1398: Vijos1382寻找主人 Necklace Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 308 Solved: 129 Descrip ...
- BZOJ1398Vijos1382寻找主人 Necklace——最小表示法
题目描述 给定两个项链的表示,判断他们是否可能是一条项链. 输入 输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的). 输出 如果两条项链不可能同构,那么输出 ...
- BZOJ1398: Vijos1382寻找主人 Necklace 字符串最小表示法
Description 给定两个项链的表示,判断他们是否可能是一条项链. Input 输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的). Output 如果 ...
- 初涉最小表示法&&bzoj1398: Vijos1382寻找主人 Necklace
把最小表示法的坑填了 Description 给定两个项链的表示,判断他们是否可能是一条项链. Input 输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的) ...
- 【bzoj1398】Vijos1382寻找主人 Necklace
*题目描述: 给定两个项链的表示,判断他们是否可能是一条项链. *输入: 输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的). *输出: 如果两条项链不可能同 ...
- vijos1382寻找主人
题目大意: 给出两个串(长度<=1e6),问是否同构,如果同构输出最小表示. 题解: 这是最小表示法模板题.在这里好好讲一下最小表示法. 首先有一个最暴力的方法:把所有表示搞出来排序. 时间复杂 ...
- vijos-1382 寻找主人
题意: 给出两个同样长度的数字串: 求两个串是否本质同样.同样则输出最小表示. 长度L似乎给的不正确,大概是2000000左右吧: 题解: 最小表示法裸题.证明正确性啥的详见论文吧: 这东西大体的思路 ...
- bzoj 1398: 寻找主人 AC自动机+最小表示法
题目大意: 给定两个序列判断是否循环同构,若循环同构则输出最小表示 题解: 因为没有样例输入输出,一开始没看到要求输出最小表示 Wa一大页. 但不得不说bzoj还是挺高效的: 赞一个 XD.jpg 判 ...
随机推荐
- JS window对象 History 对象 history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能。语法: window.history.[属性|方法]
History 对象 history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能. 注意:从窗口被打开的那一刻开始记录,每个浏览器窗口.每个标签页乃至每个框架,都 ...
- 记录一次工作中jvm被linux杀死的调查
首先,以后碰到任何jvm的错误,先看日志!!!!!!!! web项目在tomcat目录下的log里,或者自己设定的errorfile目录下.总之,找到一切可以运用的日志,比如crash日志,cored ...
- shell脚本输出空心等腰三角形
第一种:(for循环) #!/bin/bash#空心等腰三角形arr=9 #定义金字塔的层数for ((i=1;i<=$arr;i++))do for ((j=1;j<=$(($arr-$ ...
- CAS -- ABA问题的解决方案
我们现在来说什么是ABA问题.假设内存中有一个值为A的变量,存储在地址V中. 此时有三个线程想使用CAS的方式更新这个变量的值,每个线程的执行时间有略微偏差.线程1和线程2已经获取当前值,线程3还未获 ...
- Python Faker的使用 及 常用函数的查询
安装faker pip install faker faker的使用 引用:from faker import Faker 初始化:f=Faker(locale='zh_CN') # 默认是en_U ...
- element中的tree组件实现菜单分配
返回的菜单数据 tree组件的使用 <el-tree ref="menuList" // :data="menuList" // 展示数据 :props= ...
- join加入线程
join线程会抢先拿到cup来执行线程,然后其他的线程再来执行. 案例: public static void main(String args[]){ //创建线程对象 Thread myThrea ...
- Delphi 取整函数round、trunc、ceil和floor
Delphi 取整函数round.trunc.ceil和floor 1.Round(四舍六入五留双)功能说明:对一个实数进行四舍五入.(按照银行家算法)例:var i, j: Integer;begi ...
- Quick BI功能篇之(一):20分钟入门
前言: 最近小编帮助隔壁团队一个小姐姐解决了个大难题:给老板汇报业绩分析,频次提高.效率提升,还得保证团队中的小伙伴们都得有点大数据时代的基本数据能力.小编觉得这么好的经验可以分享给更多志同道合的朋友 ...
- NOIp2018集训test-9-6(am)
Problem A. divisor 发现x为k可表达一定可以表示成这种形式,如k=3,x=(1/3+1/2+1/6)x. 于是可以搜索k(k<=7)个1/i加起来等于1的情况,如果一个数是这些 ...