[JSOI2008]火星人
嘟嘟嘟
嗯。
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]火星人的更多相关文章
- 1014: [JSOI2008]火星人prefix
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MB Description 火星人最近研究了一种操作:求一个字串两个后缀 ...
- [BZOJ1014][JSOI2008]火星人prefix
[BZOJ1014][JSOI2008]火星人prefix 试题描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字 ...
- BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6243 Solved: 2007[Submit] ...
- 【bzoj1014】[JSOI2008]火星人prefix
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6031 Solved: 1917[Submit] ...
- BZOJ 1014: [JSOI2008]火星人prefix Splay+二分
1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...
- JSOI2008 火星人prefix
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2918 Solved: 866[Submit][ ...
- bzoj 1014: [JSOI2008]火星人prefix hash && splay
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3154 Solved: 948[Submit][ ...
- 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4164 Solved: 1277[Submit] ...
- BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )
用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...
- BZOJ_1014_[JSOI2008]火星人prefix_splay+hash
BZOJ_1014_[JSOI2008]火星人prefix_splay+hash 题意:火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们 ...
随机推荐
- 第一次搭建dns服务器
CentOS 7 搭建DNS服务器 主要参考的是小左先森的一篇博客:https://blog.51cto.com/13525470/2054121. 1.搭建过程中遇到的几个问题说一下: a.在重启服 ...
- 手把手教你写一个java的orm(一)
写之前的说明 其实吧. 这个东西已经写好了,地址在:https://github.com/hjx601496320/JdbcPlus 这系列文章算是我写的过程的总结吧.(恩系列,说明我可能会写好久,╮ ...
- java基础之java的基本数据类型
java分为基本数据类型和引用数据类型.基本数据类型主演分为四类八种,引用数据类型分为接口,类,数组,String. 基本数据类型的四类八种是: 整数类型:byte,short,int,long 数据 ...
- [LeetCode] Next Permutation(一种巧妙的解题方法)
Next Permutation Implement next permutation, which rearranges numbers into the lexicographically nex ...
- python 历险记(五)— python 中的模块
目录 前言 基础 模块化程序设计 模块化有哪些好处? 什么是 python 中的模块? 引入模块有几种方式? 模块的查找顺序 模块中包含执行语句的情况 用 dir() 函数来窥探模块 python 的 ...
- C# 压缩图片到指定宽度,假如图片小于指定宽度 判断图片大小是否大于指定大小(KB) 如果大于则压缩图片质量 宽高不变
class Program { static void Main(string[] args) {//G:\zhyue\backup\projects\Test\ConsoleApplication1 ...
- ionic开发中遇到的问题
开发调试过程中,会遇到这样的问题:同源策略请求url禁止请求. 一 网上搜的结果基本是2类: 1. 同源策略请求被阻止, 跨域问题,大家建议添加Access-Control-Allow-Origi ...
- ArcGIS10.3+Oracle12C+ArcGIS Server10.3安装布署(之二)
1.创建PDB 输入 dbca 命令 2.安装完成后,连接PDBSDE的容器数据库 3.环境变量 从Oracle的官方网站下载 instantclient-basic-nt-12.1.0.2.0. ...
- GridView双击行弹出窗口
protected void gvCustom_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == D ...
- JSON学习笔记-1
1.什么是JSON? JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一 ...