Codeforces 159D Palindrome pairs

http://codeforces.com/problemset/problem/159/D

题目大意:

给出一个字符串,求取这个字符串中互相不覆盖的两个回文子串的对数。

思路:num[i]代表左端点在i这个位置的回文串个数,然后用树状数组维护sum[i],代表回文串右端点小于等于i的回文串数,总复杂度:O(n^2)

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 #define ll long long
 7 ll c[200005],num[200005];
 8 int pd[2005][2005],n;
 9 char s[200005];
10 int lowbit(int x){
11     return x&(-x);
12 }
13 int read(){
14     int t=0,f=1;char ch=getchar();
15     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
16     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
17     return t*f;
18 }
19 void add(int x){
20     for (int i=x;i<=n;i+=lowbit(i)){
21         c[i]++;
22     }
23 }
24 int ask(int x){
25     int res=0;
26     for (int i=x;i;i-=lowbit(i)){
27         res+=c[i];
28     }
29     return res;
30 }
31 int main(){
32     scanf("%s",s+1);
33     n=strlen(s+1);
34     for (int i=1;i<=n;i++)
35      pd[i][i]=1,add(i),num[i]++;
36     for (int i=1;i<n;i++)
37      if (s[i]==s[i+1]) pd[i][i+1]++,add(i+1),num[i]++;
38     for (int len=3;len<=n;len++)
39      for (int i=1;i+len-1<=n;i++){
40         int j=i+len-1;
41         if (pd[i+1][j-1]&&s[i]==s[j]) pd[i][j]=1,add(j),num[i]++;
42      }
43     ll ans=0; 
44     for (int i=1;i<=n;i++)
45       ans+=ask(i-1)*((ll)(num[i]));
46     printf("%I64d\n",ans);
47     return 0;
48 }

 

posted @ 2016-06-29 21:17  GFY  阅读(208)  评论(0编辑  收藏  举报