BZOJ2555:SubString(SAM,LCT)
Description
Input
Output
Sample Input
A
QUERY B
ADD BBABBBBAAB
Sample Output
Solution
不过一边插入一边询问很显然是无法像原来一样等全部字符都插入后再排序求right集合大小的
不过根据right集合的定义,其实我们可以发现一个点的right集合大小就是子树的np节点的个数
这玩意儿只需要用LCT维护子树权值和就好了
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N (1200000+1000) 5 using namespace std; 6 7 int Father[N],Son[N][2],Size[N],Si[N],Rev[N],R[N],T,mask; 8 char s[N],opt[10]; 9 10 int Get(int x){return Son[Father[x]][1]==x;} 11 int Is_root(int x){return Son[Father[x]][0]!=x && Son[Father[x]][1]!=x;} 12 void Update(int x){Size[x]=Si[x]+Size[Son[x][0]]+Size[Son[x][1]]+R[x];} 13 14 void Pushdown(int x) 15 { 16 if (x && Rev[x]) 17 { 18 if (Son[x][0]) Rev[Son[x][0]]^=1; 19 if (Son[x][1]) Rev[Son[x][1]]^=1; 20 swap(Son[x][0],Son[x][1]); 21 Rev[x]=0; 22 } 23 } 24 25 void Rotate(int x) 26 { 27 int wh=Get(x); 28 int fa=Father[x],fafa=Father[fa]; 29 if (!Is_root(fa)) Son[fafa][Son[fafa][1]==fa]=x; 30 Son[fa][wh]=Son[x][wh^1]; Father[fa]=x; 31 Son[x][wh^1]=fa; Father[x]=fafa; 32 if (Son[fa][wh]) Father[Son[fa][wh]]=fa; 33 Update(fa); Update(x); 34 } 35 36 void Push(int x){if (!Is_root(x)) Push(Father[x]); Pushdown(x);} 37 void Splay(int x) 38 { 39 Push(x); 40 for (int fa; !Is_root(x); Rotate(x)) 41 if (!Is_root(fa=Father[x])) 42 Rotate(Get(fa)==Get(x)?fa:x); 43 } 44 45 void Access(int x) 46 { 47 for (int y=0; x; y=x,x=Father[x]) 48 { 49 Splay(x); 50 Si[x]+=Size[Son[x][1]]; Si[x]-=Size[y]; 51 Son[x][1]=y; Update(x); 52 } 53 } 54 55 void Make_root(int x){Access(x); Splay(x); Rev[x]^=1;} 56 int Find_root(int x){Access(x); Splay(x); while (Son[x][0]) x=Son[x][0]; return x;} 57 void Link(int x,int y){Make_root(x); Make_root(y); Father[x]=y; Si[y]+=Size[x]; Update(y);} 58 void Cut(int x,int y){Make_root(x); Access(y); Splay(y); Son[y][0]=Father[x]=0; Update(y);} 59 60 struct SAM 61 { 62 int fa[N],son[N][28],step[N]; 63 int p,q,np,nq,last,cnt; 64 SAM(){last=++cnt;} 65 66 void Insert(int x) 67 { 68 p=last; np=last=++cnt; step[np]=step[p]+1; R[np]=1; 69 while (p && !son[p][x]) son[p][x]=np,p=fa[p]; 70 if (!p) fa[np]=1,Link(np,1); 71 else 72 { 73 q=son[p][x]; 74 if (step[p]+1==step[q]) fa[np]=q,Link(np,q); 75 else 76 { 77 nq=++cnt; step[nq]=step[p]+1; 78 memcpy(son[nq],son[q],sizeof(son[q])); 79 Link(nq,fa[q]); Cut(q,fa[q]); Link(q,nq); Link(np,nq); 80 fa[nq]=fa[q]; fa[q]=fa[np]=nq; 81 while (son[p][x]==q) son[p][x]=nq,p=fa[p]; 82 } 83 } 84 } 85 int Query(char s[]) 86 { 87 Make_root(1); 88 int now=1, len=strlen(s); 89 for (int i=0; i<len; ++i) 90 if (son[now][s[i]-'A']) now=son[now][s[i]-'A']; 91 else return 0; 92 Access(now); Splay(now); 93 return Size[now]-Size[Son[now][0]]; 94 } 95 }SAM; 96 97 void Decode(char *s,int mask) 98 { 99 int len=strlen(s); 100 for(int i=0; i<len; ++i) 101 { 102 mask=(mask*131+i)%len; 103 swap(s[i],s[mask]); 104 } 105 } 106 107 int main() 108 { 109 scanf("%d",&T); 110 scanf("%s",s); 111 int len=strlen(s); 112 for (int i=0; i<len; ++i) 113 SAM.Insert(s[i]-'A'); 114 while (T--) 115 { 116 scanf("%s%s",opt,s); 117 int len=strlen(s); 118 Decode(s,mask); 119 if (opt[0]=='A') 120 for (int i=0; i<len; ++i) 121 SAM.Insert(s[i]-'A'); 122 else 123 { 124 int ans=SAM.Query(s); 125 printf("%d\n",ans); 126 mask^=ans; 127 } 128 } 129 }
转载于:https://www.cnblogs.com/refun/p/9378216.html
BZOJ2555:SubString(SAM,LCT)相关推荐
- SubString SAM+LCT
P5212 SubString 题意 给出字符串S和操作次数Q ADD:往S后继续加一个字符串 QUERY:求给出的字符串在S中出现次数 考虑SAM,插入是O(n)的,查询位置时O(n)的,问题是怎么 ...
- 2019.03.01 bzoj2555: SubString(sam+lct)
传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsa ...
- Bzoj2555 SubString
Time Limit: 30 Sec Memory Limit: 512 MB Submit: 2430 Solved: 719 Description 懒得写背景了,给你一个字符串init,要求 ...
- 洛谷 - P6292 区间本质不同子串个数(SAM+LCT+线段树)
题目链接:点击查看 题目大意:给出一个长度为 n 的字符串,再给出 m 次询问,每次询问需要回答区间 [ l , r ] 内有多少个本质不同的字符串 题目分析:首先简化模型,回顾一下如何求解 &quo ...
- PKUSC2018训练日程(4.18~5.30)
(总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...
- 平衡树+LCT全纪录
平衡树(splay) 平衡数模板 平衡树能干些什么呢? 插入一个数 删除一个数 查询数 x x x的排名(小于x" role="presentation" style=& ...
- 其他-私人♂收藏(比赛记录 Mar, 2019)
OwO 03.03 [USACO19JAN] A. Redistricting 题意:给 \(g\) ,求 \(f(n)\) . \(f(i)=f(j)+[g(i)\ge g(j)],j \in (i ...
- 【BZOJ4545】DQS的trie
Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...
- BZOJ 5384 有趣的字符串题(区间本质不同回文串数量)
题意: 多次求区间本质不同回文串数量. 我们知道区间本质不同子串个数是SAM+LCT+BIT. 所以区间本质不同回文串个数就是PAM+SegmentTree+BIT. 为什么可以搏一搏LCT变线段树呢 ...
- ZR2019暑期集训游记
Day2019.7.29: 在鸽了许久后,我终于过来了- 然而课已经上了两天了- Day2019.7.30: 早上很早跟着qt大佬起床了,然而还是没抢到什么好位置- 早饭看起来海星啊,但是为什么感觉人 ...
最新文章
- visualSVN-server的安装图解
- 平方的观测值表概率_茆诗松的概率论与数理统计(第六章)
- DeepLab v2的摘要部分(翻译加理解)
- [转].NET学习网站收集
- HUST 1541 Student’s question
- Linux内存page,Linux虚拟内存管理 - Page Table的作用
- 大白话带你梳理一下Dubbo的那些事儿
- Mybatis(6)CURD增删改查操作
- MySQL的初识(python开发者的第一印象)
- 编程实现 带符号减法溢出判断
- ubuntu--雷鸟只能收邮件不能发邮件
- Java Annotaion认识
- Android点赞头像列表
- JavaScript函数 思维导图
- 第一代计算机的拼音,计算机系列拼音
- 从模型制作(3dmax)到网页显示(babylonjs)全过程介绍
- 动态内存分配实现冒泡排序
- 使用曲面细分渲染毛发
- 坚果云同步的HTML编辑器,我的浏览器标签同步方案:坚果云+Floccus
- 笔记本配置连接打印机
热门文章
- 第三天:完善数据层(controller)真正对接数据库Mysql
- ThinkPhp 使用 PHP_XLSXWriter 代替 PHPExcel 百万级数据单次导出
- 刚接触新工作的程序员:直接运行include
- 使用jdk提示Assistive Technology not found: org.GNOME.Accessibility.AtkWrapper
- IDEA中安装TeaVM插件
- Dx unsupported class file version 52.0 Conversion to Dalvik format failed with error 1
- LINUX下载编译libav
- LINUX doubango编译中prefix参数无效
- JAVA对象,直接新建跟反射新建,有区别
- C中遇到错误error: jump to label [-fpermissive]的解决办法