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 ...
随机推荐
- HDU - 3085 Nightmare Ⅱ
HDU - 3085 Nightmare Ⅱ 双向BFS,建立两个队列,让男孩女孩一起走 鬼的位置用曼哈顿距离判断一下,如果该位置与鬼的曼哈顿距离小于等于当前轮数的两倍,则已经被鬼覆盖 #includ ...
- leetcode-896-单调数列
题目描述: 如果数组是单调递增或单调递减的,那么它是单调的. 如果对于所有 i <= j,A[i] <= A[j],那么数组 A 是单调递增的. 如果对于所有 i <= j,A[i] ...
- Asp.net的生命周期之应用程序生命周期
参考:http://msdn.microsoft.com/zh-cn/library/ms178473(v=vs.100).aspx 参考:http://www.cnblogs.com/JimmyZh ...
- 架构师养成记--26.vi/vim相关操作
vi/vim命令模式插入模式 aio编辑模式 : aio就是vi/vim的插入模式命令 作用a 在光标后附加文本A 在本行末附加文本i 在光标钱插 ...
- 小M的作物 最小割最大流
题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号). 现在,第i种作物种植在A中种植可 ...
- redis 远程 访问 安全配置
朋友总结很好,就转载了-> 站长博客 假设两台redis服务器,ip分别为:192.168.1.101和192.168.1.103,如果在101上通过redis-cli访问103上的redis呢 ...
- Fix the error in NeighboringCellInfo.java in CM10.1
1.error messenge: frameworks/base/telephony/java/android/telephony/NeighboringCellInfo.java:: error ...
- ASP.NET Core 中的依赖注入
目录 什么是依赖注入 ASP .NET Core 中使用依赖注入 注册 使用 释放 替换为其它的 Ioc 容器 参考 什么是依赖注入 软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要 ...
- Guava之RateLimiter的设计
Guava源码中很详尽的解释了RateLimiter的概念. 从概念上看,限流器以配置速率释放允许的请求(permit).如有必要,调用acquire()将会阻塞知道一个允许可用.一旦被获取(acqu ...
- iOS 真机测试错误“The application could not be verified”
iOS 真机测试错误"The application could not be verified" 真机测试的时候报错:"The application could no ...