题目链接

BZOJ3238

题解

简单题

经典后缀数组 + 单调栈套路,求所有后缀\(lcp\)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<map>
  5. #include<cstring>
  6. #include<algorithm>
  7. #define LL long long int
  8. #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
  9. #define REP(i,n) for (int i = 1; i <= (n); i++)
  10. #define cls(s) memset(s,0,sizeof(s))
  11. #define mp(a,b) make_pair<int,int>(a,b)
  12. #define cp pair<int,int>
  13. using namespace std;
  14. const int maxn = 500005,maxm = 100005,INF = 1000000000;
  15. inline int read(){
  16. int out = 0,flag = 1; char c = getchar();
  17. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  18. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  19. return out * flag;
  20. }
  21. char s[maxn];
  22. int sa[maxn],rank[maxn],height[maxn],bac[maxn],t1[maxn],t2[maxn],n,m;
  23. void getsa(){
  24. int *x = t1,*y = t2; m = 255;
  25. for (int i = 0; i <= m; i++) bac[i] = 0;
  26. for (int i = 1; i <= n; i++) bac[x[i] = s[i]]++;
  27. for (int i = 1; i <= m; i++) bac[i] += bac[i - 1];
  28. for (int i = n; i; i--) sa[bac[x[i]]--] = i;
  29. for (int k = 1; k <= n; k <<= 1){
  30. int p = 0;
  31. for (int i = n - k + 1; i <= n; i++) y[++p] = i;
  32. for (int i = 1; i <= n; i++) if (sa[i] - k > 0) y[++p] = sa[i] - k;
  33. for (int i = 0; i <= m; i++) bac[i] = 0;
  34. for (int i = 1; i <= n; i++) bac[x[y[i]]]++;
  35. for (int i = 1; i <= m; i++) bac[i] += bac[i - 1];
  36. for (int i = n; i; i--) sa[bac[x[y[i]]]--] = y[i];
  37. swap(x,y);
  38. x[sa[1]] = p = 1;
  39. for (int i = 2; i <= n; i++)
  40. x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p : ++p);
  41. if (p >= n) break;
  42. m = p;
  43. }
  44. for (int i = 1; i <= n; i++) rank[sa[i]] = i;
  45. for (int i = 1,k = 0; i <= n; i++){
  46. if (k) k--;
  47. int j = sa[rank[i] - 1];
  48. while (s[i + k] == s[j + k]) k++;
  49. height[rank[i]] = k;
  50. }
  51. }
  52. cp st[maxn],t;
  53. int top;
  54. void solve(){
  55. LL sum = 0,ans = 0;
  56. for (int i = 2; i <= n; i++){
  57. t = mp(height[i],1);
  58. while (top && st[top].first >= t.first){
  59. sum -= 1ll * st[top].first * st[top].second;
  60. t.second += st[top].second;
  61. top--;
  62. }
  63. st[++top] = t;
  64. sum += 1ll * t.first * t.second;
  65. ans += sum;
  66. }
  67. printf("%lld\n",1ll * n * (n + 1) * (n - 1) / 2 - 2 * ans);
  68. }
  69. int main(){
  70. scanf("%s",s + 1); n = strlen(s + 1);
  71. getsa();
  72. solve();
  73. return 0;
  74. }

BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】的更多相关文章

  1. bzoj3238 [Ahoi2013]差异 后缀数组+单调栈

    [bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  2. 【BZOJ-3238】差异 后缀数组 + 单调栈

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1561  Solved: 734[Submit][Status] ...

  3. 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈

    [BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  4. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  5. [AHOI2013] 差异 - 后缀数组,单调栈

    [AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...

  6. 【bzoj3238】差异[AHOI2013](后缀数组+单调栈)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...

  7. [BZOJ3238][AHOI2013]差异(后缀数组)

    求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j ...

  8. BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈

    BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...

  9. bzoj 3238: [Ahoi2013]差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

随机推荐

  1. LeetCode977. 有序数组的平方

    问题:977. 有序数组的平方 给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序. 示例 1: 输入:[-4,-1,0,3,10] 输出:[0,1,9,1 ...

  2. JAVA / MySql 编程——第六章 Mysql 创建账户的相关命令

    1.        创建普通用户: 语法: CREATE USER `user`@`host` [IDENTIFIED 'password'];   //user:用户名,host:主机名,passw ...

  3. Linux下 VI 编辑器操作

    VI编辑器的三种模式:命令模式.输入模式.末行模式. 1.命令模式:vi启动后默认进入的是命令模式,从这个模式使用命令可以切换到另外两种模式,同时无论在何种模式下,[Esc]键都可以回到命令模式.在命 ...

  4. Head First Java-图形化界面

    Head First Java是本挺好的书,讲的比较清楚和简单.主要看原则.概念啥的.语法什么的,还是靠谷歌吧:) 这部分的笔记也有很多了,最近会努力更新和搬运.顺便自己也重新读一下. 就酱.想要这本 ...

  5. C语言函数篇(一)函数的组成

    函数的组成: 函数名 输入参数 返回值 返回值 函数名 (输入参数){ 执行体 } 用指针保存函数: int func(int a, int b, char c){ } --> int (*fu ...

  6. python-11多线程

    1-多任务可以由多进程完成,也可以由一个进程内的多线程完成. 1.1多线程代码示例 import time, threading def loop(): print("thread %s i ...

  7. パラメータID一覧

    名称 内容 ABK 処理グループ. AUF 受注伝票タイプ. AVE FI:支払明細通知書のテンプレート登録. BAR 伝票タイプ. BNK 銀行コード. BUK 会社コード. CAC 管理領域. D ...

  8. python正则表达式02--findall()和search()方法区别,group()方法

    import re st = 'asxxixxsaefxxlovexxsdwdxxyouxxde' #search()和 findall()的区别 a = re.search('xx(.*?)xxsa ...

  9. Hive 的企业优化

    优化 数据优化 一.从大表拆分成小表(更快地检索) 引用:Hive LanguageManual DDL eg2:常用于分表 create table if not exists default.ce ...

  10. mysql安装与基本管理,mysql密码破解

    一.MySQL介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是 ...