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的更多相关文章
随机推荐
- angularJS入门小Demo【简单测试js代码的方法】
1.首先建立一个文件夹 demo, 2.在其中建立一个文本文档,改名为 demo-1.html, 3.把html中要引入的 js 文件拷贝到 demo目录下, 4.然后用 Notepadd++ 编辑刚 ...
- Windows不能用鼠标双击运行jar文件
Java应用程序jar文件可以由 JVM(Java虚拟机)直接执行,只要操作系统安装了JVM便可以运行作为Java应用程序的jar文件.可是,很多朋友遇到一个难题,那就是下载了jar文件以后在Wind ...
- Linux IO Scheduler
一直都对linux的io调度算法不理解,这段时间一直都在看这方面的内容,下面是总结和整理的网络上面的内容.生产上如何建议自己压一下.以实际为准. 每个块设备或者块设备的分区,都对应有自身的请求队列(r ...
- 中频IF
Intermediate 频率是指中频. 一般RF射频有三个频率,基带频率,中频,射频. 射频是发射到空中的频率,也就是我们一般说的2.4G, Sub-1G.但这个频率太高,不利于放大器做增益控制.所 ...
- 获取文件名称 basename 用法
<?phpheader('Content-type:text/html;charset=utf8'); $str = '2390230.png';$str_arr = explode('.',$ ...
- Babel 和 PostCss 的一些基本配置
Babel 是一个javascript编译器,PostCSS 是一个样式转换工具.两者都可以看作是一个转化平台,我们可以在上面使用一些插件,来达到想要的代码转化.几乎每个前端项目都要使用它们. Bab ...
- How GitLab uses Unicorn and unicorn-worker-killer
GitLab uses Unicorn, a pre-forking Ruby web server, to handle web requests (web browsers and Git HTT ...
- quick-cocos2d-x数据存储 UserDefault GameState io
看了quick-cocos2d-x 的framework,发现里面有一个GameState,查了下,是数据存储的类,于是稍稍总结下我用到过的数据存储方式吧. 一共是三种方法: cc.UserDefau ...
- 面试精选之Promise
常见Promise面试题 我们看一些 Promise 的常见面试问法,由浅至深. 1.了解 Promise 吗? 2.Promise 解决的痛点是什么? 3.Promise 解决的痛点还有其他方法可以 ...
- Go从入门到精通(持续更新)
1.0 搭建环境 由于我们 Go官方网站 在我大天朝被和谐了,所以我们只能去 Go语言中文网 来下载了.Go的安装很简单,不像Java还要配置一大堆的东西,选择自己系统的对应版本,下载安装,像安装QQ ...