【BZOJ1014】[JSOI2008]火星人prefix【Splay】【Hash】
2016-03-20 19:21
633 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1014
学习一发树上Hash。
10s卡时过了。
/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100005, base = 9875321;
int n, num[maxn], P[maxn];
int son[maxn][2], val[maxn], hash[maxn], pre[maxn], size[maxn];
int tot1, root;
inline void newnode(int &x, int c, int f) {
x = ++tot1;
son[x][0] = son[x][1] = 0;
val[x] = hash[x] = c;
pre[x] = f;
size[x] = 1;
}
inline void pushup(int x) {
int l = son[x][0], r = son[x][1];
size[x] = size[l] + 1 + size[r];
hash[x] = (hash[l] + (LL)P[size[l]] * val[x] % base + (LL)P[size[l] + 1] * hash[r] % base) % base;
}
inline void build(int &x, int l, int r, int f) {
if(l > r) return;
int mid = l + r >> 1;
newnode(x, num[mid], f);
build(son[x][0], l, mid - 1, x); build(son[x][1], mid + 1, r, x);
pushup(x);
}
inline void init() {
root = tot1 = 0;
son[0][0] = son[0][1] = val[0] = hash[0] = pre[0] = size[0] = 0;
newnode(root, 0, 0);
newnode(son[root][1], 0, root);
build(son[son[root][1]][0], 1, n, son[root][1]);
pushup(son[root][1]); pushup(root);
}
inline void rotate(int x) {
int y = pre[x], z = pre[y], type = son[y][1] == x;
pre[son[y][type] = son[x][!type]] = y;
pre[x] = z;
if(z) son[z][son[z][1] == y] = x;
pre[son[x][!type] = y] = x;
pushup(y); pushup(x);
}
inline void splay(int x, int goal) {
while(pre[x] != goal) {
int y = pre[x], z = pre[y];
if(z == goal) rotate(x);
else if(son[z][1] == y ^ son[y][1] == x) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
if(goal == 0) root = x;
}
inline int find(int k) {
int x = root;
while(k != size[son[x][0]] + 1)
if(k <= size[son[x][0]]) x = son[x][0];
else k -= size[son[x][0]] + 1, x = son[x][1];
return x;
}
inline int gethash(int x, int y) {
x = find(x); y = find(y + 2);
splay(x, 0); splay(y, root);
return hash[son[y][0]];
}
inline int query(int x, int y) {
int l = 1, r = tot1 - y - 1;
while(l <= r) {
int mid = l + r >> 1;
if(gethash(x, x + mid - 1) == gethash(y, y + mid - 1)) l = mid + 1;
else r = mid - 1;
}
return r;
}
inline void replace(int pos, int c) {
int x = find(pos + 1);
splay(x, 0);
val[x] = c;
pushup(x);
}
inline void insert(int pos, int c) {
int x = find(pos + 1), y = find(pos + 2);
splay(x, 0); splay(y, root);
newnode(son[y][0], c, y);
pushup(y); pushup(x);
}
char str[maxn];
int main() {
scanf("%s", str + 1); n = strlen(str + 1);
for(int i = 1; i <= n; i++) num[i] = str[i] - 'a' + 1;
P[0] = 1;
for(int i = 1; i < maxn; i++) P[i] = P[i - 1] * 27, P[i] %= base;
init();
int m; scanf("%d", &m);
while(m--) {
char ch = getchar(); for(; ch != 'Q' && ch != 'R' && ch != 'I'; ch = getchar());
if(ch == 'Q') {
int x, y; scanf("%d%d", &x, &y); if(x > y) swap(x, y);
printf("%d\n", query(x, y));
}
else if(ch == 'R') {
int x; scanf("%d%s", &x, str);
replace(x, str[0] - 'a' + 1);
}
else if(ch == 'I') {
int x; scanf("%d%s", &x, str);
insert(x, str[0] - 'a' + 1);
}
}
return 0;
}
学习一发树上Hash。
10s卡时过了。
/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100005, base = 9875321;
int n, num[maxn], P[maxn];
int son[maxn][2], val[maxn], hash[maxn], pre[maxn], size[maxn];
int tot1, root;
inline void newnode(int &x, int c, int f) {
x = ++tot1;
son[x][0] = son[x][1] = 0;
val[x] = hash[x] = c;
pre[x] = f;
size[x] = 1;
}
inline void pushup(int x) {
int l = son[x][0], r = son[x][1];
size[x] = size[l] + 1 + size[r];
hash[x] = (hash[l] + (LL)P[size[l]] * val[x] % base + (LL)P[size[l] + 1] * hash[r] % base) % base;
}
inline void build(int &x, int l, int r, int f) {
if(l > r) return;
int mid = l + r >> 1;
newnode(x, num[mid], f);
build(son[x][0], l, mid - 1, x); build(son[x][1], mid + 1, r, x);
pushup(x);
}
inline void init() {
root = tot1 = 0;
son[0][0] = son[0][1] = val[0] = hash[0] = pre[0] = size[0] = 0;
newnode(root, 0, 0);
newnode(son[root][1], 0, root);
build(son[son[root][1]][0], 1, n, son[root][1]);
pushup(son[root][1]); pushup(root);
}
inline void rotate(int x) {
int y = pre[x], z = pre[y], type = son[y][1] == x;
pre[son[y][type] = son[x][!type]] = y;
pre[x] = z;
if(z) son[z][son[z][1] == y] = x;
pre[son[x][!type] = y] = x;
pushup(y); pushup(x);
}
inline void splay(int x, int goal) {
while(pre[x] != goal) {
int y = pre[x], z = pre[y];
if(z == goal) rotate(x);
else if(son[z][1] == y ^ son[y][1] == x) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
if(goal == 0) root = x;
}
inline int find(int k) {
int x = root;
while(k != size[son[x][0]] + 1)
if(k <= size[son[x][0]]) x = son[x][0];
else k -= size[son[x][0]] + 1, x = son[x][1];
return x;
}
inline int gethash(int x, int y) {
x = find(x); y = find(y + 2);
splay(x, 0); splay(y, root);
return hash[son[y][0]];
}
inline int query(int x, int y) {
int l = 1, r = tot1 - y - 1;
while(l <= r) {
int mid = l + r >> 1;
if(gethash(x, x + mid - 1) == gethash(y, y + mid - 1)) l = mid + 1;
else r = mid - 1;
}
return r;
}
inline void replace(int pos, int c) {
int x = find(pos + 1);
splay(x, 0);
val[x] = c;
pushup(x);
}
inline void insert(int pos, int c) {
int x = find(pos + 1), y = find(pos + 2);
splay(x, 0); splay(y, root);
newnode(son[y][0], c, y);
pushup(y); pushup(x);
}
char str[maxn];
int main() {
scanf("%s", str + 1); n = strlen(str + 1);
for(int i = 1; i <= n; i++) num[i] = str[i] - 'a' + 1;
P[0] = 1;
for(int i = 1; i < maxn; i++) P[i] = P[i - 1] * 27, P[i] %= base;
init();
int m; scanf("%d", &m);
while(m--) {
char ch = getchar(); for(; ch != 'Q' && ch != 'R' && ch != 'I'; ch = getchar());
if(ch == 'Q') {
int x, y; scanf("%d%d", &x, &y); if(x > y) swap(x, y);
printf("%d\n", query(x, y));
}
else if(ch == 'R') {
int x; scanf("%d%s", &x, str);
replace(x, str[0] - 'a' + 1);
}
else if(ch == 'I') {
int x; scanf("%d%s", &x, str);
insert(x, str[0] - 'a' + 1);
}
}
return 0;
}
相关文章推荐
- JSON数据格式
- Javascript事件模型
- JavaScript 中的类型
- JS的第二周
- javascript中的对象
- js获取项目根路径
- ExtJs 同步与异步请求
- <香港科技大学html+css+js课堂笔记>week1--CSS部分--第二部分
- js中对象属性值排序(字典倒排序)
- JavaScript笔记(3)
- 简单的Gson转换json数据
- JavaScript笔记(2)
- JS+DOM实例一:鼠标滑动图片
- javascript中构造函数
- <香港科技大学html+css+js课堂笔记>week1--CSS部分
- js slideToggle 的另一种实现方式,根据不同的状态添加选中颜色
- Day02 CSS,JAVAScript
- js正则表达式具体时间的验证,当前日期跟所填日期比较大小,时间的比较
- JavaScript拥有动态类型
- 关于在servlet和action中返回json数据的一些问题