3238: [Ahoi2013]差异

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 3425  Solved: 1559
[Submit][Status][Discuss]

Description

Input

一行,一个字符串S

Output

一行,一个整数,表示所求值

Sample Input

cacao

Sample Output


54

HINT

2<=N<=500000,S由小写英文字母组成

Source

[Submit][Status][Discuss]



这题很尬。。。。。。

我能说我是看错题目才想到这种做法的吗。。?

首先对于那个和式,很容易发现和按sa数组下标的顺序算的答案是一样的

因为把两个式子乘二都等于算所有( i , j )有序対的差异

于是。。我们可以用后缀数组瞎搞。。。

建一下后缀数组,然后从后往前做,维护height的最小值的和即可

单调栈就可以了。。。然而蒟蒻很蠢居然还上了一棵线段树。。。。。。

PS.听说出题的目的是考后缀自动机。。?

代码:

#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;typedef long long LL;const int INF = 2147483647;
const int maxn = 500100;
const int maxseg = 4 * maxn;int m;
char s[maxn];
int rank[maxn],t1[maxn],t2[maxn],c[maxn];
LL siz[maxseg],sum[maxseg],ans,n,sa[maxn],sumtj,height[maxn];
bool flag[maxseg];inline void del(int o)
{flag[o] = 1; siz[o] = sum[o] = 0;
}inline void pushdown(int o)
{if (flag[o]){int lc = o * 2,rc = o * 2 + 1;del(lc); del(rc);flag[o] = 0;}
}inline void maintain(int o)
{int lc = o * 2,rc = o * 2 + 1;siz[o] = siz[lc] + siz[rc];sum[o] = sum[lc] + sum[rc];
}inline void reset(int o,int l,int r,int al,int ar)
{if (al <= l && r <= ar){del(o); return;}pushdown(o);int lc = o * 2,rc = o * 2 + 1,mid = l + r >> 1;if (ar <= mid) reset(lc,l,mid,al,ar);if (mid < al) reset(rc,mid + 1,r,al,ar);if (al <= mid && mid < ar){reset(lc,l,mid,al,mid);reset(rc,mid + 1,r,mid + 1,ar);}maintain(o);
}inline LL query(int o,int l,int r,int al,int ar)
{if (al <= l && r <= ar) return siz[o];pushdown(o);int lc = o * 2,rc = o * 2 + 1,mid = l + r >> 1;if (ar <= mid) return query(lc,l,mid,al,ar);if (mid < al) return query(rc,mid + 1,r,al,ar);if (al <= mid && mid < ar) return query(lc,l,mid,al,mid) + query(rc,mid + 1,r,mid + 1,ar);
}inline void inc(int o,int l,int r,int pos,LL cnt)
{if (l == r){sum[o] += cnt * l; siz[o] += cnt; return;}pushdown(o);int mid = l + r >> 1,lc = o * 2,rc = o * 2 + 1;if (pos <= mid) inc(lc,l,mid,pos,cnt);else inc(rc,mid + 1,r,pos,cnt);maintain(o);
}inline void build()
{int *x = t1,*y = t2;for (int i = 1; i <= m; i++) c[i] = 0;for (int i = 1; i <= n; i++) c[x[i] = s[i]]++;for (int i = 1; i <= m; i++) c[i] += c[i - 1];for (int i = n; i >= 1; i--) sa[c[x[i]]--] = i;for (int k = 1; k <= n; k <<= 1){int p = 0;for (int i = n - k + 1; i <= n; i++) y[++p] = i;for (int i = 1; i <= n; i++) if (sa[i] > k) y[++p] = sa[i] - k;for (int i = 1; i <= m; i++) c[i] = 0;for (int i = 1; i <= n; i++) c[x[y[i]]]++;for (int i = 1; i <= m; i++) c[i] += c[i - 1];for (int i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];swap(x,y);x[sa[1]] = p = 1;for (int i = 2; i <= n; i++)x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p : ++p;if (p >= n) break;m = p;}for (int i = 1; i <= n; i++) rank[sa[i]] = i;int k = 0;for (int i = 1; i <= n; i++){if (k) k--;int j = sa[rank[i] - 1];while (s[i + k] == s[j + k]) k++;height[rank[i]] = k;}
}int main()
{#ifdef dyffreopen("hyj1.txt","r",stdin);freopen("hyj2.txt","w",stdout);#endifscanf("%s",s + 1); n = strlen(s + 1);for (int i = 1; i <= n; i++) m = max(m,(int)s[i]);build();ans = 0;for (LL i = n - 1; i >= 1; i--){sumtj += n - sa[i + 1] + 1;ans += (n - sa[i] + 1) * (n - i) + sumtj;LL k = query(1,0,n,height[i + 1] + 1,n);reset(1,0,n,height[i + 1] + 1,n);inc(1,0,n,height[i + 1],k + 1);ans -= 2 * sum[1];}printf("%lld",ans);return 0;
}

【bzoj3238】[Ahoi2013]差异相关推荐

  1. BZOJ3238[Ahoi2013]差异

    BZOJ3238[Ahoi2013]差异 题目描述 n<=500000n<=500000n,都是小写字母 输入 一行,一个字符串S 输出 一行,一个整数,表示所求值 Solution 公式 ...

  2. BZOJ3238: [Ahoi2013]差异

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 4840  Solved: 2298 [Submit][Stat ...

  3. [BZOJ3238] [AHOI2013] 差异 - 后缀自动机

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1968  Solved: 896 [Submit][Statu ...

  4. bzoj3238 [Ahoi2013]差异

    题目链接 树状数组+单调栈 计算出每个后缀的前面.后面第一个h[]比它小的(前闭后开),乘起来计算答案 1 #include<algorithm> 2 #include<iostre ...

  5. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]

    题目地址 - GO-> 题目大意: 给定一个长度为 nn 的字符串SS,令TiTi表示它从第ii个字符开始的后缀,求以下这个式子的值: ∑1≤i<j≤nlen(Ti)+len(Tj)−2× ...

  6. bzoj3238 [Ahoi2013]差异 后缀自动机

    这个题虽然看起来比较麻烦,但其实有一点搞懂了就好做了 每一个后缀的前缀的lcp一定是这个串里的子串, 对于全部子串,如果它不是后缀,那一定可以找到这个串对应的后缀, 而这样的子串和后缀子串是没有区别的 ...

  7. [BZOJ3238][Ahoi2013]差异

    Time Limit: 20 Sec Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Inpu ...

  8. bzoj3238 [Ahoi2013]差异 后缀自动机

    题意:给出一个串,求其中任意两个字串的lcp的总和. 我们可以对于这个串建一颗后缀自动机,实际上,他的parent边树就是一颗后缀树,我们在后缀树上统计答案,设f表示right集合的大小,可以理解为后 ...

  9. bzoj3238: [Ahoi2013]差异(后缀自动机)

    传送门 后缀自动机好题. 题意: 做法:samsamsam 废话 考虑翻转字串,这样后缀的最长公共前缀等于前缀的最长公共后缀. 然后想到parentparentparent树上面两个串的最长公共后缀跟 ...

最新文章

  1. 习题4-3 求分数序列前N项和 (15 分)
  2. python天天向上的力量 B
  3. 剑指offer58-||.左旋转字符串
  4. 上个ensp实验只发了配置,这次是命令条目
  5. 打造一款便携版的Sublime Text
  6. Python3错误和异常
  7. “HTTPS”安全在哪里?
  8. LINUX awk操作
  9. Win11系统中的Thumbs.db文件可以删除吗?
  10. 论坛源码手机php,【校园社区APP】带后台完整社区论坛手机应用源码
  11. VMWare安装Win10虚拟机详细教程
  12. 企业微信有什么用,介绍企业微信6个强大的功能
  13. thymeleaf中三元运算符嵌套写法
  14. 首款国产太赫兹成像芯片发布
  15. 三极管为什么可以放大电流?
  16. BCI Competition 2008 – Graz dataset A个人翻译(附MATLAB安装BioSig)
  17. CICE海冰模式的编译
  18. HTML自定义滚动条附效果图和完整源码
  19. 一个80后SEOER对于SEO职业规划的三点想法
  20. 「唇语识别技术」看不透TA的心,但可以听懂TA的话

热门文章

  1. 推荐系统的评价指标笔记(NDCG、MAP、AUC、HR、MRR)
  2. 批处理文件写法(转帖)
  3. 模态分析中的阶数理解
  4. Word中使用交叉引用插入多个参考文献
  5. python调用大漠多线程_C# - 大漠多线程控制台
  6. html5 相册翻转效果,HTML5 css3:3D旋转木马效果相册
  7. 题解:女神间的 BOYI # 博弈论 # surreal number
  8. 一荣俱荣,豪取多项冠军后荣耀着手年终奖改革
  9. 建模师是个好职业吗?
  10. JAVA题目~分数类Fraction Exp03-4