bzoj3790 神奇项链(manacher+贪心)
2018-02-22 17:29
120 查看
我们用manacher处理出所有的回文串。由于机器二的特殊性质,我们发现,其实如果我们把以每一个字符为中心的最长回文串看做一条线段的话,就是问你最少需要几条线段覆盖1~n。这个问题我们可以贪心的解决。把所有线段按左端点从小到大
4000
排序,每次选一条能接上的且能延伸最远的即可。最后答案就是所需最少线段数-1.
4000
排序,每次选一条能接上的且能延伸最远的即可。最后答案就是所需最少线段数-1.
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 100020 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,p ; char s ; struct Line{ int l,r; }a ; inline bool cmp(Line a,Line b){return a.l<b.l;} int main(){ // freopen("a.in","r",stdin); while(~scanf("%s",s+1)){ n=strlen(s+1); for(int i=n;i>=1;--i) s[i<<1]=s[i],s[i<<1|1]='#'; s[1]='#';n=n<<1|1;int id=0; for(int i=1;i<=n;++i){ if(i<id+p[id]) p[i]=min(p[(id<<1)-i],id+p[id]-i); else p[i]=1; while(i-p[i]>=1&&i+p[i]<=n&&s[i-p[i]]==s[i+p[i]]) ++p[i]; if(i+p[i]>id+p[id]) id=i; a[i].l=i-p[i]+1;a[i].r=i+p[i]-1; }sort(a+1,a+n+1,cmp); int R=1,now=1,cnt=0; while(R<n){ int mx=0;while(now<=n&&a[now].l<=R) mx=max(mx,a[now].r),++now; R=mx;++cnt; }printf("%d\n",cnt-1); }return 0; }
相关文章推荐
- bzoj3790 神奇项链(manacher+贪心区间覆盖)
- [BZOJ3790]神奇项链(manacher+贪心)
- [BZOJ 3790] 神奇项链 Manacher+贪心(权限题)
- BZOJ3790 神奇项链(马拉车+BIT讲解)
- 【BZOJ3790】神奇项链 Manacher+贪心
- bzoj3790 神奇项链
- bzoj 3790: 神奇项链 (manacher+线段树优化DP)
- BZOJ 3790: 神奇项链 [Manacher 贪心]
- BZOJ 3790 神奇项链 (Manacher 贪心)
- BZOJ_3790_神奇项链_manacher+贪心
- 【BZOJ 3790】神奇项链 回文树+贪心
- bzoj 3790 神奇项链(Manacher,DP+BIT | 贪心)
- bzoj 3790 神奇项链
- 【bzoj3790】神奇项链——manacher+贪心
- BZOJ 3790 神奇项链 (manacher)
- bzoj3790 神奇项链
- [BZOJ2426][HAOI2010] 工厂选址 (神奇的贪心)
- BZOJ3790 神奇项链
- [BZOJ3790]神奇项链-manachar
- 【BZOJ-3790】神奇项链 Manacher + 树状数组(奇葩) + DP