题意

分析

考场上写了暴力建图40分溜了…(结果只得了30分)

然后只要优化建边就行了

首先给出的支配关系无法优化,就直接A向它支配的B连边.

考虑B向以B作为前缀的所有A连边,做一遍后缀数组,两个区间的左端点位置的LCP一定大于等于B的长度.在排好序的后缀数组上就是一段区间.然后用线段树优化建边.

那么用ST表倍增算一下能拓展的区间就行了.

然后由于只能向长度大于自己的连边,就按长度排序然后线段树改成主席树.

写+调一个下午…发现是sb错误…

CODE

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. char cb[1<<15],*cs=cb,*ct=cb;
  5. #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
  6. template<class T>inline void read(T &res) {
  7. char ch; while(!isdigit(ch=getc()));
  8. for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
  9. }
  10. const int MAXS = 200005;
  11. const int MAXA = 200005;
  12. const int MAXB = 200005;
  13. const int maxn = 5000005;
  14. char s[MAXS];
  15. int m, na, nb, la[MAXA], lb[MAXB], ra[MAXA], rb[MAXB], w[maxn]; //开始这里 w数组长度开成 MAXA+MAXB了...
  16. struct sub {
  17. int x, len, typ, id;
  18. sub(){}
  19. sub(int x, int len, int typ, int id):x(x), len(len), typ(typ), id(id){}
  20. inline bool operator <(const sub &o)const {
  21. return len != o.len ? len > o.len : typ < o.typ;
  22. }
  23. }Sub[MAXA+MAXB];
  24. namespace _SA { //后缀数组
  25. int f[MAXS][18], Lg[MAXS], height[MAXS], sa[MAXS], rk[MAXS], c[MAXS], x[MAXS], y[MAXS];
  26. inline void Pre(int n) { Lg[0] = -1; for(int i = 1; i <= n; ++i) Lg[i] = Lg[i>>1] + 1; }
  27. inline void Get_Height(int n) {
  28. for(int i = 1, j, k = 0; i <= n; ++i) if(rk[i] > 1) {
  29. j = sa[rk[i]-1], k = k ? k-1 : 0;
  30. while(i+k <= n && j+k <= n && s[i+k] == s[j+k]) ++k;
  31. height[rk[i]] = k;
  32. }
  33. }
  34. inline void Init_ST(int n) {
  35. for(int i = 1; i <= n; ++i) f[i][0] = height[i];
  36. for(int j = 1; j <= Lg[n]; ++j)
  37. for(int i = 1; i <= n-(1<<j)+1; ++i)
  38. f[i][j] = min(f[i][j-1], f[i+(1<<(j-1))][j-1]);
  39. }
  40. inline void Get_SA(int n, int m) {
  41. for(int i = 1; i <= m; ++i) c[i] = 0;
  42. for(int i = 1; i <= n; ++i) ++c[x[i]=s[i]-'a'+1];
  43. for(int i = 2; i <= m; ++i) c[i] += c[i-1];
  44. for(int i = n; i >= 1; --i) sa[c[x[i]]--] = i;
  45. for(int k = 1; k <= n; k<<=1) {
  46. int p = 0;
  47. for(int i = n-k+1; i <= n; ++i) y[++p] = i;
  48. for(int i = 1; i <= n; ++i) if(sa[i] > k) y[++p] = sa[i]-k;
  49. for(int i = 1; i <= m; ++i) c[i] = 0;
  50. for(int i = 1; i <= n; ++i) ++c[x[i]];
  51. for(int i = 2; i <= m; ++i) c[i] += c[i-1];
  52. for(int i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i];
  53. swap(x, y);
  54. x[sa[1]] = p = 1;
  55. for(int i = 2; i <= n; ++i)
  56. x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k]) ? p : ++p;
  57. if((m=p) == n) break;
  58. }
  59. for(int i = 1; i <= n; ++i) rk[sa[i]] = i;
  60. Get_Height(n); Init_ST(n);
  61. }
  62. }
  63. using namespace _SA;
  64. namespace Gragh { //建图
  65. int deg[maxn];
  66. vector<int> G[maxn];
  67. inline void add(int x, int y) { ++deg[y]; G[x].push_back(y); }
  68. LL dp[maxn]; int q[maxn];
  69. inline LL Get_Ans(int N) {
  70. int l = 0, r = 0;
  71. for(int i = 1; i <= N; dp[i] = w[i], ++i)
  72. if(!deg[i]) q[r++] = i;
  73. LL re = 0;
  74. while(l < r) { //topo排序
  75. int u = q[l++];
  76. re = max(re, dp[u]);
  77. for(int i = 0, siz = G[u].size(), v; i < siz; ++i) {
  78. v = G[u][i];
  79. dp[v] = max(dp[v], dp[u] + w[v]);
  80. if(!--deg[v]) q[r++] = v;
  81. }
  82. }
  83. if(r < N) re = -1;
  84. return re;
  85. }
  86. }
  87. using namespace Gragh;
  88. namespace Segment_Tree { //主席树
  89. int ls[maxn], rs[maxn], tot;
  90. void insert(int &now, int l, int r, int x, int id) {
  91. ++tot, ls[tot] = ls[now], rs[tot] = rs[now];
  92. if(now) add(tot, now);
  93. w[now = tot] = 0;
  94. if(l == r) { add(now, id); return; }
  95. int mid = (l + r) >> 1;
  96. if(x <= mid) insert(ls[now], l, mid, x, id), add(now, ls[now]);
  97. else insert(rs[now], mid+1, r, x, id), add(now, rs[now]);
  98. }
  99. void addedge(int now, int l, int r, int x, int y, int id) {
  100. if(!now || y < l || x > r) return;
  101. if(x <= l && r <= y) { add(id, now); return; }
  102. int mid = (l + r) >> 1;
  103. addedge(ls[now], l, mid, x, y, id);
  104. addedge(rs[now], mid+1, r, x, y, id);
  105. }
  106. }
  107. using namespace Segment_Tree;
  108. int main () {
  109. int T; read(T);
  110. Pre(200000);
  111. while(T--) {
  112. int N = 0;
  113. while(isalpha(s[++N]=getc()));
  114. Get_SA(--N, 26);
  115. read(na);
  116. for(int i = 1; i <= na; ++i)
  117. read(la[i]), read(ra[i]), Sub[i] = sub(rk[la[i]], w[i]=ra[i]-la[i]+1, 0, i);
  118. read(nb);
  119. for(int i = 1; i <= nb; ++i)
  120. read(lb[i]), read(rb[i]), Sub[na + i] = sub(rk[lb[i]], rb[i]-lb[i]+1, 1, i), w[na+i] = 0;
  121. sort(Sub + 1, Sub + na + nb + 1);
  122. tot = na + nb; int rt = 0;
  123. for(int i = 1; i <= na + nb; ++i) {
  124. if(!Sub[i].typ) insert(rt, 1, N, Sub[i].x, Sub[i].id);
  125. else {
  126. int l = Sub[i].x, r = Sub[i].x;
  127. for(int j = Lg[l-1]; ~j; --j)
  128. if(l > (1<<j) && f[l-(1<<j)+1][j] >= Sub[i].len) l -= 1<<j;
  129. for(int j = Lg[N-r]; ~j; --j)
  130. if(r < N && f[r+1][j] >= Sub[i].len) r += 1<<j;
  131. addedge(rt, 1, N, l, r, na + Sub[i].id);
  132. }
  133. }
  134. read(m);
  135. for(int i = 1, x, y; i <= m; ++i)
  136. read(x), read(y), add(x, na + y);
  137. printf("%lld\n", Get_Ans(tot));
  138. for(int i = 1; i <= tot; ++i)
  139. deg[i] = ls[i] = rs[i] = 0, G[i].clear();
  140. ls[0] = rs[0] = 0;
  141. }
  142. }

常数巨大

BZOJ 5496: [2019省队联测]字符串问题 (后缀数组+主席树优化建图+拓扑排序)的更多相关文章

  1. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  2. bzoj 5496: [2019省队联测]字符串问题【SAM+拓扑】

    有一个想法就是暴力建图,把每个A向有和他相连的B前缀的A,然后拓扑一下,这样的图是n^2的: 考虑优化建图,因为大部分数据结构都是处理后缀的,所以把串反过来,题目中要求的前缀B就变成了后缀B 建立SA ...

  3. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  4. BZOJ4556 [Tjoi2016&Heoi2016]字符串 【后缀数组 + 主席树 + 二分 + ST表】

    题目 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职 ...

  5. BZOJ 2865 字符串识别 | 后缀数组 线段树

    集训讲字符串的时候我唯一想出正解的题-- 链接 BZOJ 2865 题面 给出一个长度为n (n <= 5e5) 的字符串,对于每一位,求包含该位的.最短的.在原串中只出现过一次的子串. 题解 ...

  6. BZOJ 4556(后缀数组+主席树求前驱后继+二分||后缀数组+二分+可持久化线段树)

    换markdown写了.. 题意: 给你一个1e5的字符串,1e5组询问,求\([l_1,r_1]\)的所有子串与\([l_2,r_2]\)的lcp 思路: 首先可以发现答案是具有单调性的,我们考虑二 ...

  7. BZOJ3473:字符串(后缀数组,主席树,二分,ST表)

    Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...

  8. BZOJ4556:[TJOI\HEOI2016]字符串(后缀数组,主席树,二分,ST表)

    Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱 ...

  9. [BZOJ4556][Tjoi2016&Heoi2016]字符串 后缀数组+主席树

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MB Description 佳媛姐姐过生日的时候,她的小 ...

随机推荐

  1. [转帖]Linux系列之SAR命令使用详解

    Linux系列之SAR命令使用详解 sar是System Activity Reporter(系统活动情况报告)的缩写.这个工具所需要的负载很小,也是目前linux中最为全面的性能分析工具之一.此款工 ...

  2. python学习-11 运算符2

    布尔值 1.真 true 假false name = 'abc' c = 'c' in name print(c) 运算结果: True Process finished with exit code ...

  3. c++学习总结(一)------类结构学习

    基类的构造函数并没有被派生类继承 析构函数和拷贝赋值操作符同样也没有 类的设计者通过把成员函数声明为 const 以表明它们不修改类对象 把一个修改类数据成员的函数声明为 const 是非法的 (51 ...

  4. 分布排序(distribution sorts)算法大串讲

    ref : https://dsqiu.iteye.com/blog/1707383   本文内容框架: §1 鸽巢排序(Pigeonhole) §2 桶排序(Bucket Sort)   §3 基数 ...

  5. php 配置微信公众号

    首先你要在微信公众号官网申请一个公众号,然后登录进去 在网页的左下方找到开发的基本配置 就可以开始配置服务器下面的东西了 点击打开成这个样子的 就是一些参数,url填写你自己服务器的具体地址就好了,我 ...

  6. SOLID Principles

    Intention: more understandable, easier to maintain and easier to extend.(通过良好的设计使得代码easy and simple, ...

  7. docker系列五之数据卷(volumn)

    docker数据卷(volumn) 一. 为什么需要数据卷 docker镜像是由多个文件系统(只读层)叠加而成,当我们启动一个容器的时候,docker的服务端会加载镜像的只读层,并在最顶层创建一个可读 ...

  8. wangeditor富编辑器在node和vue前后台分离的使用

    本来是想用百度的ueditor编辑器来达到想要的功能的,但在使用中,感觉前后台分离上,需要引入的东西过多,不轻量:然后就去尝试用wangeditor(这个名字听着感觉有点太随意的感觉....但功能上还 ...

  9. C# 交换排序

    用交换排序的方式实现对int类型的数组arrays从小到大排序 思路: 第一步:一个长度为n的数组,把最小的放第一行,第二小的数字放第二行,,,, 0(0为数组的第一项) 第一小的数字 1      ...

  10. Vue中遍历数组的新方法

    1.foreach foreach循环对不能使用return来停止循环 search(keyword){ var newList = [] this.urls.forEach(item =>{ ...