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

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

 1 /**************************************************************
 2     Problem: 3790
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:176 ms
 7     Memory:3716 kb
 8 ****************************************************************/
 9  
10 //BZOJ 3790
11 #include<vector>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 #define pb push_back
21 #define mk make_pair
22 #define fi first
23 #define se second
24 using namespace std;
25 typedef long long LL;
26 typedef pair<int,int> pii;
27 inline int getint(){
28     int r=1,v=0; char ch=getchar();
29     for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
30     for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
31     return r*v;
32 }
33 const int N=1e5+10,INF=~0u>>2;
34 /*******************template********************/
35 char s[N];
36 int a[N],p[N],f[N],d[N],n,m,size=0;
37 pii seg[N];
38 void get_seg(int l,int r){
39     if(l>r)return;
40     seg[++size]=mk(l,r);
41 }
42 bool cmp(pii a,pii b){
43     return a.se==b.se ? a.fi<b.fi : a.se<b.se;
44 }
45 void update(int x,int v){
46     for(;x;x-=x&-x) d[x]=min(d[x],v);
47 }
48 int query(int x){
49     int r=d[x];
50     for(;x && x<=size;x+=x&-x) r=min(d[x],r);
51     return r;
52 }
53 int main(){
54     while(scanf("%s",s)!=EOF){
55         memset(d,0x7f,sizeof d); d[0]=0;
56         memset(a,0,sizeof a);
57         memset(f,0,sizeof f);
58         m=n=strlen(s);
59         F(i,1,n) a[i<<1]=s[i-1];
60         n=n<<1|1; size=0;
61         int id=0,mx=0;
62         F(i,1,n){
63             if(mx>i) p[i]=min(p[2*id-i],mx-i);
64             else p[i]=0;
65             while(i-p[i]-1>0 && i+p[i]+1<=n && a[i-p[i]-1]==a[i+p[i]+1])p[i]++;
66             get_seg((i-p[i]+1)/2,(i+p[i]-1)/2);
67             if (p[i]+i>mx) mx=p[i]+i,id=i;
68         }
69         sort(seg+1,seg+size+1,cmp);
70         int ans=INF;
71         F(i,1,size){
72             f[i]=query(seg[i].fi-1)+1;
73             if (seg[i].se==m) ans=min(ans,f[i]);
74             update(seg[i].se,f[i]);
75         }
76         printf("%d\n",ans-1);
77     }
78     return 0;
79 }
View Code

相关文章: