题目链接 \(Click\) \(Here\)

这题质量不错,就是暴力分有点足\(hhhhhhhh\),整整有\(95\)分。

(搞得我写完暴力都不想写正解直接理解思路之后就直接水过去了\(QwQ\))

(啊好啦好啦水过去是我的锅啦,我自己出来挨打还不行嘛\(QAQ\))

其实就是把\(AABB\)换成求\(AA\)然后组合在一块,最后的部分需要推一个奇妙的性质,这里我也不好叙述,详情请见这个大佬的博客。至于求\(AA\)的方法可以考虑使用后缀数组+\(RMQ\)实现\(O(1)\)匹配。

(别跟我提哈希听着就来气\(TwT\),为什么还可以用\(Hash\)水啊喂!)

\(95pts:\)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 4010;
  4. char s[N];
  5. int n, m, T;
  6. int sa[N], tp[N], rk[N], _rk[N], bin[N], height[N];
  7. void get_height () {
  8. int k = 0;
  9. for (int i = 1; i <= n; ++i) {
  10. if (k != 0) --k;
  11. int j = sa[rk[i] - 1];
  12. while (s[i + k - 1] == s[j + k - 1]) ++k;
  13. height[rk[i]] = k;
  14. }
  15. }
  16. void base_sort () {
  17. for (int i = 1; i <= m; ++i) bin[i] = 0;
  18. for (int i = 1; i <= n; ++i) bin[rk[tp[i]]]++;
  19. for (int i = 1; i <= m; ++i) bin[i] += bin[i - 1];
  20. for (int i = n; i >= 1; --i) sa[bin[rk[tp[i]]]--] = tp[i];
  21. }
  22. void suffix_sort () {
  23. m = 255;
  24. for (int i = 1; i <= n; ++i) {
  25. tp[i] = i, rk[i] = s[i - 1];
  26. }
  27. base_sort ();
  28. for (int w = 1; w <= n; w <<= 1) {
  29. int cnt = 0;
  30. for (int i = n - w + 1; i <= n; ++i) {
  31. tp[++cnt] = i;
  32. }
  33. for (int i = 1; i <= n; ++i) {
  34. if (sa[i] > w) {
  35. tp[++cnt] = sa[i] - w;
  36. }
  37. }
  38. base_sort ();
  39. memcpy (_rk, rk, sizeof (rk));
  40. rk[sa[1]] = cnt = 1;
  41. for (int i = 2; i <= n; ++i) {
  42. rk[sa[i]] = (_rk[sa[i]] == _rk[sa[i - 1]]) && (_rk[sa[i] + w] == _rk[sa[i - 1] + w]) ? cnt : ++cnt;
  43. }
  44. if (cnt == n) break;
  45. m = cnt;
  46. }
  47. }
  48. int a[N], b[N], st[N][25];
  49. void get_STlist () {
  50. memset (st, 0, sizeof (st));
  51. for (int i = 1; i <= n; ++i) {
  52. st[i][0] = height[i];
  53. }
  54. int mx = log2 (n);
  55. for (int i = 1; i <= mx; ++i) {
  56. for (int j = 1; j + (1 << i) - 1 <= n; ++j) {
  57. st[j][i] = min (st[j][i - 1], st[j + (1 << (i - 1))][i - 1]);
  58. }
  59. }
  60. }
  61. int lcp (int x, int y) {
  62. if (x > y) swap (x, y); ++x;
  63. if (x > y) return 0;
  64. int mx = log2 (y - x + 1);
  65. return min (st[x][mx], st[y - (1 << mx) + 1][mx]);
  66. }
  67. void Initialize () {
  68. memset (a, 0, sizeof (a));
  69. memset (b, 0, sizeof (b));
  70. memset (s, 0, sizeof (s));
  71. memset (sa, 0, sizeof (sa));
  72. memset (tp, 0, sizeof (tp));
  73. memset (rk, 0, sizeof (rk));
  74. memset (height, 0, sizeof (height));
  75. scanf ("%s", s);
  76. n = strlen (s);
  77. }
  78. int main () {
  79. cin >> T;
  80. while (T--) {
  81. Initialize ();
  82. suffix_sort ();
  83. get_height ();
  84. get_STlist ();
  85. for (int i = 0; i < n; ++i) { //枚举每一个后缀
  86. for (int l = 1; i + l * 2 - 1 < n; ++l) {
  87. // printf ("lcp (rk[%d] = %d, rk[%d] = %d) = %d\n", i, rk[i], i + l, rk[i + l], lcp (rk[i], rk[i + l]))
  88. if (lcp (rk[i + 1], rk[i + l + 1]) >= l) {
  89. a[i + l * 2 - 1]++, b[i]++;
  90. }
  91. }
  92. }
  93. long long ans = 0;
  94. for (int i = 0; i < n; ++i) {
  95. ans += a[i] * b[i + 1];
  96. }
  97. cout << ans << endl;
  98. }
  99. }

\(100pts\)

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. #define LL long long
  8. #define Set(a, v) memset(a, v, sizeof(a))
  9. #define For(i, a, b) for(int i = (a); i <= (int)(b); i++)
  10. #define Forr(i, a, b) for(int i = (a); i >= (int)(b); i--)
  11. #define LOG (15+5)
  12. #define MAXN (30000+5)
  13. int n, c[MAXN], c1[MAXN], c2[MAXN], Log[MAXN];
  14. struct SuffixArray{
  15. char s[MAXN];
  16. int sa[MAXN], h[MAXN][LOG], rank[MAXN];
  17. void init(){
  18. Set(c1, 0); Set(c2, 0);
  19. }
  20. void buildsa(int m='z'){
  21. int *x = c1, *y = c2;
  22. For(i, 1, m) c[i] = 0;
  23. For(i, 1, n) c[x[i]=s[i]]++;
  24. For(i, 1, m) c[i] += c[i-1];
  25. Forr(i, n, 1) sa[c[x[i]]--] = i;
  26. int p;
  27. for(int k = 1; k <= n; k <<= 1){
  28. p = 0;
  29. For(i, n-k+1, n) y[++p] = i;
  30. For(i, 1, n) if(sa[i] > k) y[++p] = sa[i]-k;
  31. For(i, 1, m) c[i] = 0;
  32. For(i, 1, n) c[x[y[i]]]++;
  33. For(i, 1, m) c[i] += c[i-1];
  34. Forr(i, n, 1) sa[c[x[y[i]]]--] = y[i];
  35. swap(x, y);
  36. p = x[sa[1]] = 1;
  37. For(i, 2, n) x[sa[i]] = (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])? p: ++p;
  38. if(p >= n) break;
  39. m = p;
  40. }
  41. }
  42. void getheight(){
  43. For(i, 1, n) rank[sa[i]] = i;
  44. int k = 0, j;
  45. For(i, 1, n){
  46. if(k) k--;
  47. j = sa[rank[i]+1];
  48. if(rank[i] == n) continue;
  49. while(s[i+k] == s[j+k]) k++;
  50. h[rank[i]][0] = k;
  51. }
  52. For(j, 1, 15) For(i, 1, n){
  53. if(i+(1<<(j-1)) > n) break;
  54. h[i][j] = min(h[i][j-1], h[i+(1<<(j-1))][j-1]);
  55. }
  56. }
  57. int LCP(int x, int y){
  58. x = rank[x]; y = rank[y];
  59. if(x > y) swap(x, y);
  60. int k = Log[y-x];
  61. return min(h[x][k], h[y-(1<<k)][k]);
  62. }
  63. }A, B;
  64. int st[MAXN], en[MAXN];
  65. int main(){
  66. For(i, 2, MAXN-1) Log[i] = Log[i>>1]+1;
  67. int T;
  68. scanf("%d", &T);
  69. while(T--){
  70. A.init(); B.init();
  71. Set(st, 0); Set(en, 0);
  72. scanf("%s", A.s+1);
  73. n = strlen(A.s+1);
  74. For(i, 1, n) B.s[i] = A.s[n-i+1];
  75. A.buildsa(); A.getheight();
  76. B.buildsa(); B.getheight();
  77. int j, x, y, t;
  78. For(L, 1, n/2){
  79. for(int i=L, j=i+L; j <= n; i+=L,j+=L){
  80. x = min(A.LCP(i,j), L), y = min(B.LCP(n-(i-1)+1, n-(j-1)+1), L-1);
  81. t = x+y-L+1;
  82. if(x+y >= L){
  83. st[i-y]++; st[i-y+t]--;
  84. en[j+x-t]++; en[j+x]--;
  85. }
  86. }
  87. }
  88. For(i, 1, n) st[i]+=st[i-1], en[i]+=en[i-1];
  89. LL ans = 0;
  90. For(i, 1, n) ans += 1LL*en[i]*st[i+1];
  91. printf("%lld\n", ans);
  92. }
  93. return 0;
  94. }

Luogu P1117 [NOI2016]优秀的拆分的更多相关文章

  1. UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组、ST表)

    连NOI Day1T1都不会做...看了题解都写不出来还要抄Claris的代码.. 题目链接: (luogu)https://www.luogu.org/problemnew/show/P1117 ( ...

  2. P1117 [NOI2016]优秀的拆分

    $ \color{#0066ff}{ 题目描述 }$ 如果一个字符串可以被拆分为\(AABB\)的形式,其中 A和 B是任意非空字符串,则我们称该字符串的这种拆分是优秀的. 例如,对于字符串\(aab ...

  3. 并不对劲的bzoj4650:loj2083:uoj219:p1117:[NOI2016]优秀的拆分

    题目大意 "优秀的拆分"指将一个字符串拆分成AABB的形式 十次询问,每次给出一个字符串S(\(|S|\leq3*10^4\)),求它的所有子串的优秀的拆分的方案数之和 题解 此题 ...

  4. luogu1117 [NOI2016]优秀的拆分

    luogu1117 [NOI2016]优秀的拆分 https://www.luogu.org/problemnew/show/P1117 后缀数组我忘了. 此题哈希可解决95分(= =) 设\(l_i ...

  5. [NOI2016]优秀的拆分&&BZOJ2119股市的预测

    [NOI2016]优秀的拆分 https://www.lydsy.com/JudgeOnline/problem.php?id=4650 题解 如果我们能够统计出一个数组a,一个数组b,a[i]表示以 ...

  6. 【BZOJ4560】[NOI2016]优秀的拆分

    [BZOJ4560][NOI2016]优秀的拆分 题面 bzoj 洛谷 题解 考虑一个形如\(AABB\)的串是由两个形如\(AA\)的串拼起来的 那么我们设 \(f[i]\):以位置\(i\)为结尾 ...

  7. [UOJ#219][BZOJ4650][Noi2016]优秀的拆分

    [UOJ#219][BZOJ4650][Noi2016]优秀的拆分 试题描述 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 A 和 B 是任意非空字符串,则我们称该字符串的这种拆分是优秀 ...

  8. [NOI2016]优秀的拆分(SA数组)

    [NOI2016]优秀的拆分 题目描述 如果一个字符串可以被拆分为 \(AABB\) 的形式,其中 A和 B是任意非空字符串,则我们称该字符串的这种拆分是优秀的. 例如,对于字符串 \(aabaaba ...

  9. 题解-NOI2016 优秀的拆分

    NOI2016 优秀的拆分 \(T\) 组测试数据.求字符串 \(s\) 的所有子串拆成 \(AABB\) 形式的方案总和. 数据范围:\(1\le T\le 10\),\(1\le n\le 3\c ...

随机推荐

  1. js的常用文档对象,document

    1.document的概念:window的子对象,由于DOM对象模型的默认对象就是window,因此Window对象中的方法和子对象不需要通过Window来引用. - 2.document的组成:属性 ...

  2. 学习 Spring (十七) Spring 对 AspectJ 的支持 (完结)

    Spring入门篇 学习笔记 @AspectJ 的风格类似纯 java 注解的普通 java 类 Spring 可以使用 AspectJ 来做切入点解析 AOP 的运行时仍旧是纯的 Spring AO ...

  3. codeforces-div2-449-B

    题意:确定一个回文偶数十进制数字,输入k和q,求前k小的和对q取余的值 解题思路:首先确定一个,第k个回文偶数一定前半段一定是k,比如第12个,这个数就是1221: 代码: #include<i ...

  4. OneinStack——PHP多版本共存

    前言 我事先安装的是LNMP环境,PHP版本为7.2,但是现在环境需要一个PHP5.6,所以就准备安装个上版本,顺带写个安装教程,写完后我发现了原来有直接安装的命令!所以后面的内容大家可以忽略了!从配 ...

  5. 我的POI代码库(持续更新)

    添加的maven依赖是 <poi.version>3.15</poi.version> ... <dependency> <groupId>org.ap ...

  6. git 出现stderr: error: bad signature fatal: index file corrupt

    命令执行依次: $ rm -f .git/index $ git reset 重启即可

  7. crawlspider_房多多

    框架写起来代码是真的简洁多了,还有就是在requests爬取房多多的时候,无法爬取所有地区,而这个就不受影响 代码请查看码云 运行结果:

  8. 利用saltstack批量安装clamav杀毒软件

    源码包安装: clamav_source: file.managed: - name: /tmp/clamav-0.99.2.tar.gz - unless: test -f /tmp/clamav- ...

  9. 【COGS2652】秘术「天文密葬法」(长链剖分,分数规划)

    [COGS2652]秘术「天文密葬法」(长链剖分,分数规划) 题面 Cogs 上面废话真多,建议直接拉到最下面看一句话题意吧: 给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σa ...

  10. html图像、绝对路径和相对路径,链接

    html图像 <img>标签可以在网页上插入一张图片,它是独立使用的标签,通过"src"属性定义图片的地址,通过"alt"属性定义图片加载失败时显示 ...