BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)
题意
Sol
一眼splay + 二分hash,不过区间splay怎么写来着呀
试着写了两个小时发现死活不对
看了一下yyb的代码发现自己根本就不会splay。。。。
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int MAXN = 1e6 + 10;
const ull base = 27;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
char s[MAXN];
int root, tot, ch[MAXN][2], fa[MAXN], siz[MAXN];
ull ha[MAXN], val[MAXN], po[MAXN];
bool rev[MAXN];
int ident(int x) {
return ch[fa[x]][1] == x;
}
void connect(int x, int f, int id) {
fa[x] = f; ch[f][id] = x;
}
void update(int x) {
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
ha[x] = ha[ch[x][0]] + val[x] * po[siz[ch[x][0]]] + po[siz[ch[x][0]] + 1] * ha[ch[x][1]];
}
void rotate(int x) {
int y = fa[x], R = fa[y], Yson = ident(x), Rson = ident(y);
int B = ch[x][Yson ^ 1];
connect(x, R, Rson); connect(B, y, Yson); connect(y, x, Yson ^ 1);
update(y); update(x);
}
void splay(int x, int to) {
//to = fa[to];
while(fa[x] != to) {
if(fa[fa[x]] == to) rotate(x);
else if(ident(x) == ident(fa[x])) rotate(fa[x]), rotate(x);
else rotate(x), rotate(x);
}
if(!to) root = x; update(x);
}
int find(int k) {
int x = root;
while(1) {
if(siz[ch[x][0]] + 1 == k) return x;
if(siz[ch[x][0]] + 1 < k) k -= siz[ch[x][0]] + 1, x = ch[x][1];//tag
else x = ch[x][0];
}
}
ull gethash(int l, int len) {
int x = find(l), y = find(l + len + 1);
splay(x, 0); splay(y, x);
return ha[ch[y][0]];
}
int LCP(int y, int x) {
int l = 0, r = tot - max(x, y) - 1, ans = 0;
while(l <= r) {
int mid = l + r >> 1;
if(gethash(x, mid) == gethash(y, mid)) l = mid + 1, ans = mid;
else r = mid - 1;
}
return ans;
}
void insert(int x, int v) {
int l = find(x + 1), r = find(x + 2);
splay(l, 0); splay(r, l);
val[++tot] = v; fa[tot] = r; ch[r][0] = tot; splay(tot, 0);
}
void change(int x, int v) {
int l = find(x), r = find(x + 2);
splay(l, 0); splay(r, l);
val[ch[r][0]] = v; update(ch[r][0]);
update(r); update(l);
}
int main() {
// freopen("a.in", "r", stdin);freopen("a.out", "w", stdout);
po[0] = 1;
for(int i = 1; i <= (int)1e5; i++) po[i] = base * po[i - 1];
scanf("%s", s + 1); N = strlen(s + 1);
ch[1][1] = 2; fa[2] = 1; tot = 2; root = 1; update(2); update(1);
for(int i = 1; i <= N; i++)
insert(i - 1, s[i]);
int M = read();
while(M--) {
char opt[3]; scanf("%s", opt);
if(opt[0] == 'Q') {int x = read(), y = read(); printf("%d\n", LCP(x, y));}
else if(opt[0] == 'R') {
int x = read(); scanf("%s", opt + 1);
change(x, opt[1]);
} else {
int x = read(); scanf("%s", opt + 1);
insert(x, opt[1]);
}
}
return 0;
}
/*
*/
BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)的更多相关文章
- BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6243 Solved: 2007[Submit] ...
- 【BZOJ-1014】火星人prefix Splay + 二分 + Hash
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5852 Solved: 1871[Submit] ...
- BZOJ1014[JSOI2008]火星人prefix(splay维护hash)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- [BZOJ1014] [JSOI2008] 火星人prefix (splay & 二分答案)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- BZOJ 1014: [JSOI2008]火星人prefix Splay+二分
1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...
- bzoj1014: [JSOI2008]火星人prefix splay+hash+二分
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- BZOJ 1014 [JSOI2008]火星人prefix (splay+二分答案+字符串hash)
题目大意:维护一个字符串,支持插入字符和替换字符的操作,以及查询该字符串两个后缀的最长公共前缀长度 乍一看以为是后缀数组,然而并没有可持久化后缀数组(雾) 看题解才知道这是一道splay题,首先要对s ...
- bzoj1014: [JSOI2008]火星人prefix splay+hash
我写的代码好像自古以来就是bzoj不友好型的 本地跑的比std快,但是交上去巧妙被卡 答案...应该是对的,拍了好久了 #include <bits/stdc++.h> #define M ...
- [bzoj1014](JSOI2008)火星人 prefix (Splay维护哈希)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀. 比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...
随机推荐
- QuantLib 金融计算——数学工具之数值积分
目录 QuantLib 金融计算--数学工具之数值积分 概述 常见积分方法 高斯积分 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之数值积分 载入模 ...
- 12个值得关注的顶级可视化JS库 涉及图表、动画、时间处理,表格操作
本文是译文,原文是https://da-14.com/blog/top-11...我在原文的基础上加了百度的Echats图表库,这个也是毫不逊色其他图表库的.另外Handsontable电子表格库也是 ...
- Android手游2048核心功能
private void swipeUp(){ //向上滑动函数 for (int x = 0; x < 4; x++) { //行从上到下 for (int y = 0; y < 4; ...
- 什么是Java代码的编译与反编译?(转)
转自:http://java.tedu.cn/ask/203119.html Java代码的编译与反编译 一.什么是编译 1.利用编译程序从源语言编写的源程序产生目标程序的过程. 2.用编译程序产生目 ...
- javascript005_Object
•我们目前为止大多数引用类型都是Object类型的实例,Object也是ECMAScript中使用最多的一种类型(就像java.lang.Object一样,Object类型是所有它的实例的基础). – ...
- Mysql5.7 半同步改进
Mysql5.6半同步策略 Mysql 5.6在半同步的时候,采用的是After Commit策略.即在主库上commit了之后,等待从库返回确认. 在这里,首先会出现幻读的问题,即当前连接的事务读取 ...
- 草稿-把vim变成IDE
从昨天下午到现在一直在研究vim,初学者,从vim最基本的命令开始看起的.是通过vimtutor学习的. 看到最后一章的时候,发现原来vimtutor中的知识知识vim中的冰山一角,vim真正的强大之 ...
- 修复PHP支持的标准JSON数据格式
PHP的json_decode无法解析的JSON数据,代码如下: $json = "{rst:5,c:[ [1018485,2,0,0,0,0,'','0-0','','',2,0,2],[ ...
- 弗格森&红魔
本周日曼联对阵斯旺西时,一位名叫皮特-莫利纽克斯的58岁老人,将会举起一张老旧的床单,就如他曾做过的那样.那一次“臭名昭着”的行为要追溯到1989年12月,弗格森当时已经来到了悬崖边上,他的背后是一堵 ...
- java并发编程(8)原子变量和非阻塞的同步机制
原子变量和非阻塞的同步机制 一.锁的劣势 1.在多线程下:锁的挂起和恢复等过程存在着很大的开销(及时现代的jvm会判断何时使用挂起,何时自旋等待) 2.volatile:轻量级别的同步机制,但是不能用 ...