您的位置:首页 > 其它

【BZOJ】【3790】神奇项链

2015-04-07 16:30 381 查看

Manacher算法/DP

  找出所有的回文串,看做是一个个线段,那么问题就转化成了用最少的线段将整个区间覆盖起来,可以重叠,那么这就是一个DP了= =

  Orz ZKY大爷,让蒟蒻开眼界了……头一次知道原来树状数组还可以反过来用0.0

/**************************************************************
Problem: 3790
User: Tunix
Language: C++
Result: Accepted
Time:176 ms
Memory:3716 kb
****************************************************************/

//BZOJ 3790
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
#define mk make_pair
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
inline int getint(){
int r=1,v=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
return r*v;
}
const int N=1e5+10,INF=~0u>>2;
/*******************template********************/
char s
;
int a
,p
,f
,d
,n,m,size=0;
pii seg
;
void get_seg(int l,int r){
if(l>r)return;
seg[++size]=mk(l,r);
}
bool cmp(pii a,pii b){
return a.se==b.se ? a.fi<b.fi : a.se<b.se;
}
void update(int x,int v){
for(;x;x-=x&-x) d[x]=min(d[x],v);
}
int query(int x){
int r=d[x];
for(;x && x<=size;x+=x&-x) r=min(d[x],r);
return r;
}
int main(){
while(scanf("%s",s)!=EOF){
memset(d,0x7f,sizeof d); d[0]=0;
memset(a,0,sizeof a);
memset(f,0,sizeof f);
m=n=strlen(s);
F(i,1,n) a[i<<1]=s[i-1];
n=n<<1|1; size=0;
int id=0,mx=0;
F(i,1,n){
if(mx>i) p[i]=min(p[2*id-i],mx-i);
else p[i]=0;
while(i-p[i]-1>0 && i+p[i]+1<=n && a[i-p[i]-1]==a[i+p[i]+1])p[i]++;
get_seg((i-p[i]+1)/2,(i+p[i]-1)/2);
if (p[i]+i>mx) mx=p[i]+i,id=i;
}
sort(seg+1,seg+size+1,cmp);
int ans=INF;
F(i,1,size){
f[i]=query(seg[i].fi-1)+1;
if (seg[i].se==m) ans=min(ans,f[i]);
update(seg[i].se,f[i]);
}
printf("%d\n",ans-1);
}
return 0;
}


View Code

3790: 神奇项链

Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 126 Solved: 63
[Submit][Status][Discuss]

Description

母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字
母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H
购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和
一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或
abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。

Input

输入数据有多行,每行一个字符串,表示目标项链的样式。

Output

多行,每行一个答案表示最少需要使用第二个机器的次数。

Sample Input

abcdcba

abacada

abcdef

Sample Output

0

2

5

HINT

每个测试数据,输入不超过 5行

每行的字符串长度小于等于 50000

Source

[Submit][Status][Discuss]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: