hdu5782
官方题解不是很详细
首先有一个结论:若A=pa+sa B=pb+sb
A、B串循环同构,则可以构造一个可行方案(pa,sb) (sa,pb)中有一个是最长匹配,这个不难用反证法证明。
对于s1,s2串,我们穷举s1的每一个后缀i,设s1[i..i+len-1]=s2[0..len-1] len是最长匹配
那么不难得到,如果存在k使得k<=len且s1[0..i-1]=s2[k..k+i-1]
那么,两串前缀s1[0..i+k-1]为循环同构
因此我们预处理w[i][j]表示s1[0..i]=s2[j..j+i]是否相等,w数组我们可用bitset压位存储
求出这个数组我们只需要建立后缀数组然后顺着height[]找即可
下面我们在将变量代换,前缀p=i+k-1循环同构的条件为i-1<=p<=len+i-1且w[i-1][p]为1
这个条件我们在压位的情况下可以用位运算处理
问题得解
#include<bits/stdc++.h> using namespace std;
bitset<> w[],ans,pre[],tmp;
char s2[],s1[];
int d[],lg[],h[],s[],rk[],sa[],x[],y[],a[];
int f[][],n;
pair<int,int> q[];
bool cmp(int a,int b,int j)
{
if (y[a]==y[b])
{
if (a+j<=n&&b+j<=n) return y[a+j]!=y[b+j];
else if (a+j>n&&b+j>n) return ;
else return ;
}
return y[a]!=y[b];
} void suffix()
{
int m=;
memset(s,,sizeof(s));
for (int i=; i<=n; i++) s[a[i]]++;
for (int i=; i<=m; i++) s[i]+=s[i-];
for (int i=n; i; i--) sa[s[a[i]]--]=i;
int p=; rk[sa[]]=;
for (int i=; i<=n; i++)
{
if (a[sa[i]]!=a[sa[i-]]) ++p;
rk[sa[i]]=p;
}
int j=; m=p;
while (m<n)
{
memcpy(y,rk,sizeof(rk));
memset(s,,sizeof(s));
p=;
for (int i=n-j+; i<=n; i++) x[++p]=i;
for (int i=; i<=n; i++)
if (sa[i]>j) x[++p]=sa[i]-j;
for (int i=; i<=n; i++) s[rk[i]=y[x[i]]]++;
for (int i=; i<=m; i++) s[i]+=s[i-];
for (int i=n; i; i--) sa[s[rk[i]]--]=x[i];
rk[sa[]]=; p=;
for (int i=; i<=n; i++)
{
if (cmp(sa[i],sa[i-],j)) ++p;
rk[sa[i]]=p;
}
m=p; j<<=;
}
p=; h[]=;
for (int i=; i<=n; i++)
{
if (rk[i]==) continue;
int j=sa[rk[i]-];
while (i+p<=n&&j+p<=n&&a[i+p]==a[j+p]) ++p;
h[rk[i]]=p;
if (p) p--;
}
} int ask(int x,int y)
{
int k=lg[y-x+];
return min(f[x][k],f[y-d[k]+][k]);
} void rmq()
{
for (int i=; i<=n; i++)
f[i][]=h[i];
for (int j=; j<=lg[n]; j++)
{
for (int i=; i<=n; i++)
if (i+d[j]-<=n) f[i][j]=min(f[i][j-],f[i+d[j-]][j-]);
else break;
}
} int main()
{
// freopen("1002.in","r",stdin);
d[]=; lg[]=;
for (int i=; i<=; i++)
{
d[i]=d[i-]*;
for (int j=d[i-]; j<=min(,d[i]-); j++) lg[j]=i-;
}
pre[][]=;
for (int i=; i<; i++)
{
pre[i]=pre[i-];
pre[i][i]=;
}
while (scanf("%s%s",s1,s2)!=EOF)
{
int l=strlen(s1);
n=;
for (int i=; i<l; i++) a[++n]=s1[i]-'a'+;
a[++n]=;
for (int i=; i<l; i++) a[++n]=s2[i]-'a'+;
a[n+]=;
suffix(); rmq();
for (int i=; i<l; i++) w[i].reset();
int len=n,m=;
for (int i=rk[]+; i<=n; i++)
{
len=min(len,h[i]);
if (!len) break;
else if (sa[i]>l+) q[++m]=make_pair(len-,sa[i]-l-);
}
len=h[rk[]];
for (int i=rk[]-; i; i--)
{
if (!len) break;
else if (sa[i]>l+) q[++m]=make_pair(len-,sa[i]-l-);
len=min(len,h[i]);
}
sort(q+,q++m);
tmp.reset(); int j=m;
for (int i=l-; i>=; i--)
{
while (j&&q[j].first==i) tmp[q[j--].second]=;
w[i]=tmp;
}
ans.reset();
for (int i=; i<l; i++)
{
int x=rk[i+],y=rk[l+];
if (x>y) swap(x,y);
len=ask(x+,y);
if (len)
{
if (i) ans|=(pre[i-]^pre[i+len-])&(w[i-]<<(i-));
else ans|=pre[len-];
}
}
for (int i=; i<l; i++)
if (ans[i]) printf(""); else printf("");
puts("");
}
}
hdu5782的更多相关文章
随机推荐
- HDU 5645
DZY Loves Balls Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others ...
- 替换Jar包中的一个文件 Replace a file in a JAR
例如: jar uf myJarFile.jar com\vsoft\servlet\myServlet.class This will replace the class myServlet.cla ...
- 【Luogu】 P3928 SAC E#1 - 一道简单题 Sequence2
[题目]洛谷10月月赛R1 提高组 [算法]递推DP+树状数组 [题解]列出DP递推方程,然后用树状数组维护前后缀和. #include<cstdio> #include<cstri ...
- html+js实现的触屏版贪吃蛇
查看线上demo(服务器经常断开,推荐下载源码本地打开): http://47.93.103.19:8044/client/ ; 使用手机打开或者chrome浏览器的手机模式打开 源码地址 :http ...
- Python标准库笔记(2) — re模块
re模块提供了一系列功能强大的正则表达式(regular expression)工具,它们允许你快速检查给定字符串是否与给定的模式匹配(match函数), 或者包含这个模式(search函数).正则表 ...
- monkey测试===什么是monkey测试(系列一)转
本文转自:http://www.cnblogs.com/liu-ke/p/4353926.html Monkey工具使用 一. 什么是Monkey Monkey是Android中的一个命令行工具,可以 ...
- interrupted()和isInterrupted()比较+终止线程的正确方法+暂停线程
interrupted():测试当前线程[运行此方法的当前线程]是否已经是中断状态,执行后具有将状态标志清除为false的功能. isInterrupted():测试线程对象是否已经是中断状态,但不清 ...
- 【codeforces85D】
去实验培训回来了……写个题先玩玩 这题给人一种平衡树的感觉 但是呢,实际上操作离线+离散化+线段树一样能做 #include<bits/stdc++.h> #define lson (o& ...
- iOS一个项目开始创建, 部署到git服务器
在做iOS开发时, 最开始可能你的经理部署项目, 所以你不会插手, 只是直接从git上clone下来然后就开始撸码, 如果有一天你做经理了, 你怎么去部署一个项目呢, 下面我来过一遍流程 1. 首先需 ...
- 004_ssh连接慢的问题的解决?
<1>群中同学遇到的问题,我之前在uuwatch也遇到了同样的问题? 问个问题师兄们 突然之间 公司服务器连接很慢 连一个shell需要10几秒钟 服务器就在公司全是内网服务器, 我也不知 ...