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 ...
随机推荐
- python 之 爬普房网
from bs4 import BeautifulSoupimport reimport requestsimport pandas## pa pufangwangclass down(object) ...
- Java_锁Synchronized
锁(synchronized):既然线程之间是并发执行,就必然会有资源冲突的时候,如果不加以限制,很可能会出现死锁现象,这时就需要锁来对线程获取资源的限制程序中,可以给类,方法,代码块加锁.1.方法锁 ...
- leetcode-6-Z字形变换
题目描述: 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数: P A H N A P L S I I G Y I R 之后从左往右,逐行读取字符:" ...
- 编辑距离 区间dp
题目描述 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1.删除一个字符: 2.插入一个字符: 3.将一个字符改为另一个字符: !皆为小写字 ...
- Mondrian系列
1.Mondrian Schema Workbench 概念及常用参数 2.Schema Workbench 启动慢解决办法 3.自己写的第一个Schema文件 4.维度-退化维度 5.维度-共享维度 ...
- [ZJOI2019]Minimax搜索
先求出根节点的权值\(w\).根据套路,我们对于每个\(k\),计算\(w(s)\leq k\)的方案数,差分得到答案.为了方便,接下来考虑计算概率而不是方案数. 可以发现,对于一个给定的有解的子集, ...
- 修改docker的port端口映射
原以为修改docker的端口映射只是一条命令就可以搞定,结果发现没那么简单,记录一下以防忘记.1. 查看需要修改的容器,记住container iddocker ps -a2. 停止容器docker ...
- Office 的下载、安装和激活(图文详细)
不多说,直接上干货! 在这里,推荐一个很好的网址,http://www.itellyou.cn/ 销售渠道不同,激活通道也不同.有零售版,有大客户版.零售的用零售密钥激活,一对一. SW开头或在中间有 ...
- js读取cookie信息
1. 第一种方式读取cookie信息:用document.cookie.split(“; “)的方式把字符串分割成几个段,然后遍历整个数组 //javascript方法 function getCoo ...
- [PY3]——过滤数据——列表推导、filter()、itertools.compress()
问题 你有一个数据序列,想利用一些规则从中提取出需要的值或者是缩短序列 解决方案 最简单的过滤数据的方法,就是使用列表推导. 使用列表推导的一个潜在缺陷就是如果输入非常大的时候会产生一个非常大的结果集 ...