嘟嘟嘟




嗯。




splay维护哈希。

如题,用splay维护哈希,查找的时候二分。所以复杂度是取决于询问复杂度:\(O(n \log^ 2{n})\)。

这道题还有一个技巧,就是一个节点记录的是他的子树的哈希值,所以树的的形态改变的同时,每一个节点记录的哈希值也在改变。在pushup的时候,应该这么写:\(t[now].has = t[l].has * base ^ {t[r].siz + 1} + (s[now] - 'a') * base ^ {t[r].siz} + t[r].has\)。




然后好像就没什么好说的啦,各种操作的中心思想都是通过旋转前驱后继提取区间。

然后注意\(base\)别取字符集大小,我因为取了\(26\)导致大的点没过去,应该是取的太小导致冲突的概率比较大吧。

然而取\(27\)就过了~

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int m;
ull p[maxn];
char s[maxn], c[2], tp[2]; struct Tree
{
int ch[2], fa;
int siz; ull has;
}t[maxn];
int root, ncnt = 0; void _PrintTr(int now)
{
if(!now) return;
printf("nd:%d ls:%d rs:%d\n", now, t[now].ch[0], t[now].ch[1]);
_PrintTr(t[now].ch[0]); _PrintTr(t[now].ch[1]);
} void pushup(int now)
{
int l = t[now].ch[0], r = t[now].ch[1];
t[now].siz = t[l].siz + t[r].siz + 1;
t[now].has = t[l].has * p[t[r].siz + 1] + (s[now] - 'a') * p[t[r].siz] + t[r].has;
}
void rotate(int x)
{
int y = t[x].fa, z = t[y].fa, k = (t[y].ch[1] == x);
t[z].ch[t[z].ch[1] == y] = x; t[x].fa = z;
t[y].ch[k] = t[x].ch[k ^ 1]; t[t[y].ch[k]].fa = y;
t[x].ch[k ^ 1] = y; t[y].fa = x;
pushup(y); pushup(x);
}
void splay(int x, int s)
{
while(t[x].fa != s)
{
int y = t[x].fa, z = t[y].fa;
if(z != s)
{
if((t[z].ch[0] == y) ^ (t[y].ch[0] == x)) rotate(x);
else rotate(y);
}
rotate(x);
}
if(!s) root = x;
}
void build(int L, int R, int f)
{
if(L > R) return;
int mid = (L + R) >> 1;
if(L == R) t[L].siz = 1, t[L].has = s[L] - 'a';
else build(L, mid - 1, mid), build(mid + 1, R, mid);
t[f].ch[mid > f] = mid; t[mid].fa = f;
pushup(mid);
}
int rnk(int k)
{
int now = root;
while(1)
{
if(k <= t[t[now].ch[0]].siz) now = t[now].ch[0];
else if(k == t[t[now].ch[0]].siz + 1) return now;
else k -= (t[t[now].ch[0]].siz + 1), now = t[now].ch[1];
}
}
void update(int x)
{
int now = rnk(x); splay(now, 0);
s[now] = tp[0];
pushup(now);
}
void insert(int x)
{
int a = rnk(x), b = rnk(x + 1);
splay(a, 0); splay(b, a);
s[++ncnt] = tp[0];
t[ncnt].has = tp[0] - 'a';
t[ncnt].siz = 1;
t[ncnt].ch[0] = t[ncnt].ch[1] = 0;
t[b].ch[0] = ncnt; t[ncnt].fa = b;
pushup(b); pushup(a);
}
bool judge(int x, int y, int len)
{
if(x + len > ncnt || y + len > ncnt) return 0;
int a = rnk(x - 1), b = rnk(x + len);
splay(a, 0); splay(b, a);
//_PrintTr(root);
//puts("~~~~~~~~~~~~~~~~~~");
ull has1 = t[t[b].ch[0]].has;
a = rnk(y - 1), b = rnk(y + len);
splay(a, 0); splay(b, a);
//_PrintTr(root);
ull has2 = t[t[b].ch[0]].has;
return has1 == has2;
}
int query(int x, int y)
{
int L = 0, R = ncnt;
while(L < R)
{
int mid = (L + R + 1) >> 1;
if(judge(x, y, mid)) L = mid;
else R = mid - 1;
}
return L;
} int main()
{
p[0] = 1; for(int i = 1; i < maxn; ++i) p[i] = p[i - 1] * 47; //学姐强啊
scanf("%s", s + 2); ncnt = strlen(s + 2) + 2;
s[1] = s[ncnt] = 'f';
build(1, ncnt, 0);
for(int i = 1; i <= ncnt && !root; ++i) if(!t[i].fa) root = i;
m = read();
for(int i = 1, x; i <= m; ++i)
{
scanf("%s", c); x = read() + 1;
if(c[0] == 'Q')
{
int y = read() + 1;
write(query(x, y)), enter;
}
else
{
scanf("%s", tp);
if(c[0] == 'R') update(x);
else insert(x);
}
//_PrintTr(root);
}
return 0;
}

[JSOI2008]火星人的更多相关文章

  1. 1014: [JSOI2008]火星人prefix

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MB Description 火星人最近研究了一种操作:求一个字串两个后缀 ...

  2. [BZOJ1014][JSOI2008]火星人prefix

    [BZOJ1014][JSOI2008]火星人prefix 试题描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字 ...

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

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

  4. 【bzoj1014】[JSOI2008]火星人prefix

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

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

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

  6. JSOI2008 火星人prefix

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

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

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

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

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

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

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

  10. BZOJ_1014_[JSOI2008]火星人prefix_splay+hash

    BZOJ_1014_[JSOI2008]火星人prefix_splay+hash 题意:火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们 ...

随机推荐

  1. 第一次搭建dns服务器

    CentOS 7 搭建DNS服务器 主要参考的是小左先森的一篇博客:https://blog.51cto.com/13525470/2054121. 1.搭建过程中遇到的几个问题说一下: a.在重启服 ...

  2. 手把手教你写一个java的orm(一)

    写之前的说明 其实吧. 这个东西已经写好了,地址在:https://github.com/hjx601496320/JdbcPlus 这系列文章算是我写的过程的总结吧.(恩系列,说明我可能会写好久,╮ ...

  3. java基础之java的基本数据类型

    java分为基本数据类型和引用数据类型.基本数据类型主演分为四类八种,引用数据类型分为接口,类,数组,String. 基本数据类型的四类八种是: 整数类型:byte,short,int,long 数据 ...

  4. [LeetCode] Next Permutation(一种巧妙的解题方法)

    Next Permutation Implement next permutation, which rearranges numbers into the lexicographically nex ...

  5. python 历险记(五)— python 中的模块

    目录 前言 基础 模块化程序设计 模块化有哪些好处? 什么是 python 中的模块? 引入模块有几种方式? 模块的查找顺序 模块中包含执行语句的情况 用 dir() 函数来窥探模块 python 的 ...

  6. C# 压缩图片到指定宽度,假如图片小于指定宽度 判断图片大小是否大于指定大小(KB) 如果大于则压缩图片质量 宽高不变

    class Program { static void Main(string[] args) {//G:\zhyue\backup\projects\Test\ConsoleApplication1 ...

  7. ionic开发中遇到的问题

    开发调试过程中,会遇到这样的问题:同源策略请求url禁止请求. 一   网上搜的结果基本是2类: 1. 同源策略请求被阻止, 跨域问题,大家建议添加Access-Control-Allow-Origi ...

  8. ArcGIS10.3+Oracle12C+ArcGIS Server10.3安装布署(之二)

    1.创建PDB 输入 dbca 命令 2.安装完成后,连接PDBSDE的容器数据库 3.环境变量 从Oracle的官方网站下载   instantclient-basic-nt-12.1.0.2.0. ...

  9. GridView双击行弹出窗口

    protected void gvCustom_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == D ...

  10. JSON学习笔记-1

    1.什么是JSON? JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一 ...