题意

题目链接

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)的更多相关文章

  1. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit] ...

  2. 【BZOJ-1014】火星人prefix Splay + 二分 + Hash

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5852  Solved: 1871[Submit] ...

  3. BZOJ1014[JSOI2008]火星人prefix(splay维护hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  4. [BZOJ1014] [JSOI2008] 火星人prefix (splay & 二分答案)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  5. BZOJ 1014: [JSOI2008]火星人prefix Splay+二分

    1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...

  6. bzoj1014: [JSOI2008]火星人prefix splay+hash+二分

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  7. BZOJ 1014 [JSOI2008]火星人prefix (splay+二分答案+字符串hash)

    题目大意:维护一个字符串,支持插入字符和替换字符的操作,以及查询该字符串两个后缀的最长公共前缀长度 乍一看以为是后缀数组,然而并没有可持久化后缀数组(雾) 看题解才知道这是一道splay题,首先要对s ...

  8. bzoj1014: [JSOI2008]火星人prefix splay+hash

    我写的代码好像自古以来就是bzoj不友好型的 本地跑的比std快,但是交上去巧妙被卡 答案...应该是对的,拍了好久了 #include <bits/stdc++.h> #define M ...

  9. [bzoj1014](JSOI2008)火星人 prefix (Splay维护哈希)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀. 比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...

随机推荐

  1. 多并发编程基础 之进程 Process

    原贴  https://www.cnblogs.com/gbq-dog/p/10299663.html 1. 进程的理论知识 1.1 操作系统的背景知识 顾名思义,进程即正在执行的一个过程.进程是对正 ...

  2. TX2 刷机时遇到Parsing board information failed

    因为之前调试I2C时,修改了EEPROM Layout,所以,在刷机时遇到此问题. 解决办法是按照此文档中的介绍来修改布局. 实际操作时,我拿了一块正常的TX2,按照指令: sudo i2cdump ...

  3. python中TAB补全

    tab补全的代码文件tab.py #!/usr/bin/env python # python startup file import sys import readline import rlcom ...

  4. 在Azuer创建自己的Linux_VM

    ---恢复内容开始--- emm..就是想搭个自己的VPN去YouTube看看视屏找找资源什么的... (滑稽.jpg)然后发现似乎需要这个玩意儿 先去申请一个Azuer账户 然后根据要求一步步来就好 ...

  5. Mac 10.12安装Git管理工具SourceTree

    说明:Git的GUI工具应该是这款最好用. 下载: (链接: https://pan.baidu.com/s/1mhRr35Y 密码: vv67)

  6. wusir 线程间操作无效: 从不是创建控件“”的线程访问它 解决办法

    利用FileSystemWatcher设计一个文件监控系统时,如果一个文件被修改或者新建,则文件修改事件会被多次触发而产生多条信息.为了将一个文件被修改一次而产生的多条信息归结为一条,在设计中新开了一 ...

  7. python_SMTP and POP3

    #!/usr/bin/python #coding=utf-8 #发送邮件 import smtplib from smtplib import SMTP as smtp import getpass ...

  8. Cocos文档案例游戏设计的梳理与分析

    导语:这是一篇新手教程,适用于已看完Cocos官方文档,但还对游戏设计.运行流程不熟悉的新人.这篇教程是对文档[快速上手]里那款名叫"摘星星"的坑爹小游戏(文档原话)流程的梳理,以 ...

  9. Kaggle之路,与强者为伍——记Santander交易预测

    Kaggle--Santander Customer Transaction Prediction 原题链接 题目 Description 预测一个乘客在未来会不会交易,不计交易次数,只要有交易即为1 ...

  10. 我爱Markdown (3)

    继续Markdown的常见语法, 本文将介绍: 07 - Links 链接 08 - Images 图片 09 - Blockquotes 块引用 10 - Backslash Escapes 显示保 ...