题意:给你一个字符串,再给你一个q(询问个数1000000),问你这个区间内回文串的个数。
解题思路:
1)dp,先把 i 到j 是回文串的真值赋值给 dp[i][j] ,然后从后往前dp dp[i][j] += dp[i+1][j] + dp[i][j-1] -dp[i+1][j-1];
解题代码:
1 // File Name: 245h.dp.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月30日 星期一 15时27分10秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 #define maxn 5005 26 using namespace std; 27 int dp[maxn][maxn]; 28 char str[maxn]; 29 int n; 30 int main(){ 31 scanf("%s",&str[1]); 32 n = strlen(&str[1]); 33 for(int i = 1;i <= n;i ++) 34 { 35 if(str[i] == str[i+1]) 36 dp[i][i+1] = 1; 37 dp[i][i] = 1; 38 } 39 for(int i = n;i >= 1;i --) 40 { 41 for(int j = i+1;j <= n;j ++) 42 { 43 if(dp[i+1][j-1] == 1&& str[i] == str[j]) 44 { 45 dp[i][j] = 1; 46 } 47 } 48 } 49 for(int i = n;i >= 1;i --) 50 for(int j = i ;j <= n ;j ++) 51 { 52 dp[i][j] += dp[i+1][j] + dp[i][j-1] -dp[i+1][j-1]; 53 } 54 int q; 55 scanf("%d",&q); 56 while(q--) 57 { 58 int l , r ; 59 scanf("%d %d",&l,&r); 60 printf("%d\n",dp[l][r]); 61 } 62 return 0; 63 }
2)树状数组 + 离线 。。。 发现线段树过不了 毕竟我写的线段树常数太大。
解题代码:
1 // File Name: 245h.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月30日 星期一 11时09分19秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 char str[6000]; 28 map<int ,int >dpj[5005]; 29 map<int ,int >dpo[5005]; 30 map<int ,int >::iterator tp; 31 struct qu{ 32 int l , r,si; 33 }a[1000005]; 34 int ans[1000005]; 35 int q, n ; 36 int cmp(qu a, qu b) 37 { 38 return a.l > b.l ; 39 } 40 int tree[6005]; 41 int lowbit(int x) 42 { 43 return x & -x; 44 } 45 void update(int x) 46 { 47 while(x <= n) 48 { 49 tree[x] += 1; 50 x += lowbit(x); 51 } 52 } 53 int getsum(int r) 54 { 55 int ans = 0 ; 56 while(r >= 1) 57 { 58 ans += tree[r]; 59 r -= lowbit(r); 60 } 61 return ans; 62 } 63 inline void read_int(int &ret){ 64 char ch = getchar(); 65 while(!isdigit(ch)){ 66 ch = getchar(); 67 } 68 ret =0 ; 69 while(isdigit(ch)){ 70 ret = ret*10 + ch -‘0‘ ; 71 ch = getchar(); 72 } 73 } 74 int main(){ 75 // freopen("input","r",stdin); 76 // freopen("output","w",stdout); 77 clock_t be ,en ; 78 be = clock(); 79 scanf("%s",&str[1]); 80 scanf("%d",&q); 81 for(int i = 1;i <=q ;i ++) 82 { 83 read_int(a[i].l); 84 read_int(a[i].r); 85 a[i].si = i ; 86 } 87 sort(a+1,a+1+q,cmp); 88 n = strlen(&str[1]); 89 int tt = 1; 90 for(int i = n;i >= 1;i --) 91 { 92 dpj[i][1] = i; 93 update(i); 94 if(str[i] == str[i+1]) 95 { 96 dpo[i][2] = i+1; 97 update(i+1); 98 } 99 for(tp = dpj[i+1].begin() ; tp != dpj[i+1].end();tp++) 100 { 101 if(str[i] == str[tp->second +1]) 102 { 103 dpj[i][tp->first+2] = tp->second +1; 104 update(tp->second+1); 105 } 106 } 107 for(tp = dpo[i+1].begin() ; tp != dpo[i+1].end();tp++) 108 { 109 if(str[i] == str[tp->second +1]) 110 { 111 dpo[i][tp->first+2] = tp->second +1; 112 update(tp->second+1); 113 } 114 } 115 while(a[tt].l == i && tt <= q) 116 { 117 ans[a[tt].si] = getsum(a[tt].r); 118 tt++; 119 } 120 if(tt >q) 121 break; 122 dpj[i+1].clear(); 123 dpo[i+1].clear(); 124 } 125 for(int i = 1;i <= q; i ++) 126 printf("%d\n",ans[i]); 127 en = clock(); 128 // printf("%lf\n",(en -be)*1.0/CLOCKS_PER_SEC); 129 return 0; 130 }
时间: 2024-10-10 17:59:55