【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1014

【题意】



让你在线查询最长公共前缀.

支持单节点修改;

插入操作;

【题解】

/*
伸展树会保证
这棵树的中序遍历的结果是s[1..n]
即整个序列;
在进行旋转操作的时候,这个性质能被保持住;
伸展树在维护的时候;
每次会把需要操作的节点转到根节点;
然后进行对应的操作;
我们在进行
LCQ(x,y)的时候,
先二分枚举长度len;
然后把
x-1,x+len的节点编号获取a1,a2;
y-1,y+len的节点编号也获取b1,b2;
然后把a1转到根节点,a2放到根节点(也就是a1)的下面;
因为x+len>x-1所以a2肯定是在a1的右儿子处;
而这个时候a2的左子树代表的字符就是
s[x..x+len-1]了;
相应的对b1,b2也做同样的事情
也能获取s[y..y+len-1];
根据伸展树维护的hash值判断这两个子串是否相同。。
如果相同的话,就可以让len边长一点;
不同的话,肯定不能变长了,就变短一点呗.
然后返回答案就好 插入操作的话;
先提取x节点,把它转到根节点的位置;
然后再提取x+1号节点,把它转到根节点的下方
这里x+1号节点的左儿子肯定是空的,因为x和x+1是连在一起的;
中间不可能还有比x+1小的了;
则把这个新插入的节点放在x+1号节点的左边. 修改操作就简答多了
直接找到那个节点;
然后把它转到根节点去;
再修改它的值;
这里记住每次都把节点转到根节点就好 头部和尾部都要加一个空节点;
这样做写插入操作会好写一点吧? hash值可以搜一下RKhash;
这里不用管它会溢出;
你开一个unsigned long long就可以毁天灭地了;
let it go~~
*/

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL unsigned long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define which(x) (ch[fa[x]][1]==x) typedef pair<int, int> pii;
typedef pair<LL, LL> pll; const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 1e5 + 200;
const LL seed = 131; char s[N], str[N], op[10], val[10];
int m, n, fa[N], tot, ch[N][2], root, x, siz[N];
LL po_w[N], has[N]; void push_up(int x)
{
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
has[x] = has[ch[x][0]] + po_w[siz[ch[x][0]]] * str[x] + po_w[siz[ch[x][0]] + 1] * has[ch[x][1]];
} int build(int l, int r, int rt)
{
if (l > r) return 0;
int mid = (l + r) >> 1;
int x = ++tot;
fa[x] = rt; str[x] = s[mid];
ch[x][0] = build(l, mid - 1, x);
ch[x][1] = build(mid + 1, r, x);
push_up(x);
return x;
} int Rank(int x, int k)
{
if (siz[ch[x][0]] >= k)
return Rank(ch[x][0], k);
else
if (k == siz[ch[x][0]] + 1)
return x;
else
return Rank(ch[x][1], k - siz[ch[x][0]] - 1);
} void Rotate(int x)
{
int f = fa[x];
bool k = which(x);
ch[f][k] = ch[x][!k];
ch[x][!k] = f;
ch[fa[f]][which(f)] = x;
fa[ch[f][k]] = f;
fa[x] = fa[f];
fa[f] = x;
siz[x] = siz[f], has[x] = has[f];
push_up(f);
} void Splay(int x, int g)
{
while (fa[x] != g)
{
int f = fa[x];
if (fa[f] == g)
{
Rotate(x);
break;
}
if (which(x) ^ which(f))
Rotate(x);
else
Rotate(f);
Rotate(x);
}
if (!g) root = x;
} void Change(int pos, char val)
{
int x = Rank(root, pos);
Splay(x, 0);
str[x] = val;
push_up(x);
} void Insert(int pos, char val)
{
int x = Rank(root, pos), y = Rank(root, pos + 1);
Splay(x, 0), Splay(y, x);
ch[y][0] = ++tot;
str[tot] = val, fa[tot] = y;
push_up(tot), push_up(y), push_up(x);
} int lcq(int tx, int ty)
{
int l = 0, r = n, ans = 0;
while (l <= r)
{
int mid = (l + r) >> 1;
if (ty + mid - 1 > n + 1) //?????
{
r = mid - 1;
continue;
}
//[tx..tx+mid-1] but (tx-1,tx+mid)
int x = Rank(root, tx - 1), y = Rank(root, tx + mid);
Splay(x, 0), Splay(y, x);
LL temp1 = has[ch[y][0]];
x = Rank(root, ty - 1), y = Rank(root, ty + mid);
Splay(x, 0), Splay(y, x);
if (temp1 == has[ch[y][0]])
{
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
return ans;
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
po_w[0] = 1;
rep1(i, 1, N - 2)
po_w[i] = po_w[i - 1] * seed;
scanf("%s", s + 1);
n = strlen(s + 1);
root = build(0, n + 1, 0);
rei(m);
rep1(i, 1, m)
{
scanf("%s", op);
if (op[0] == 'R')
{
scanf("%d%s", &x, val);
Change(x + 1, val[0]);
}
else
if (op[0] == 'I')
{
scanf("%d%s", &x, val);
Insert(x + 1, val[0]);
n++;
}
else
if (op[0] == 'Q')
{
int x, y;
scanf("%d%d", &x, &y);
if (x > y)
swap(x, y);
if (x != y)
printf("%d\n", lcq(x + 1, y + 1));
else
printf("%d\n", n - x + 1);
}
}
return 0;
}

【BZOJ 1014】 [JSOI2008]火星人prefix的更多相关文章

  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: [JSOI2008]火星人prefix Splay+二分

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

  3. bzoj 1014: [JSOI2008]火星人prefix hash && splay

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

  4. 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix

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

  5. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

  6. BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)

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

  7. [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】

    题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...

  8. BZOJ 1014: [JSOI2008]火星人prefix

    Sol Splay+Hash+二分答案. 用Splay维护Hash,二分答案判断. 复杂度 \(O(nlog^2n)\) PS:这题调了两个晚上因为没开long long.许久不写数据结构题感觉写完整 ...

  9. bzoj 1014 [JSOI2008]火星人prefix(splay+hash)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP ...

  10. bzoj 1014 [JSOI2008]火星人prefix——splay+哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...

随机推荐

  1. Mycat 读写分离+分库分表

    上次进过GTID复制的学习记录,已经搭建好了主从复制的服务器,现在利用现有的主从复制环境,加上正在研究的Mycat,实现了主流分布式数据库的测试 Mycat就不用多介绍了,可以实现很多分布式数据库的功 ...

  2. 并发,two

    引言 为了更加形象的描述并发的基础知识,因此本文LZ采用了园子里一度大火的标题形式--"没听说过XXXX,就不要说你XXXX了".希望能够给猿友们一个醒目的警醒,借此来普及并发的基 ...

  3. Altium Designer如何删除以布的线

  4. 2013腾讯编程马拉松||HDU 4505 小Q系列故事——电梯里的爱情 水水水

    http://acm.hdu.edu.cn/showproblem.php?pid=4505 题目大意: 电梯最开始在0层,并且最后必须再回到0层才算一趟任务结束.假设在开始的时候已知电梯内的每个人要 ...

  5. 安装配置Rancher管理docker

    原文:安装配置Rancher管理docker 版权声明:本文为博主原创文章,转载请注明地址http://blog.csdn.net/tianyaleixiaowu. https://blog.csdn ...

  6. 再记AE与AO的区别与联系

    原文地址:转:ArcObjects与ArcEngine作者:梦游   ArcObjects(简称AO),一般都是指ArcGIS Desktop版本的组件开发集,即需要安装ArcGIS桌面版软件后才能安 ...

  7. xml 标准字符过滤

    今天在代码里面看见一串非常奇怪的推断语句 if (c < 0x9 || c > 0x9 && c < 0xA || c > 0xA && c & ...

  8. 去哪网实习总结:用到的easyui组件总结(JavaWeb)

    本来是以做数据挖掘的目的进去哪网的,结构却成了系统开发... 只是还是比較认真的做了三个月,老师非常认同我的工作态度和成果.. . 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题,分享 ...

  9. Microsoft Bot Framework 链接至微信公共号

    如何将 Microsoft Bot Framework 链接至微信公共号   说到 Microsoft Bot Framework 其实微软发布了已经有一段时间了,有很多朋友可能还不太了解,微软Bot ...

  10. zabbix自定义监控mysql

    创建用户: use mysql; grant all privileges on *.* to 'zabbix'@'%' identified by 'zabbixpasswd'; grant all ...