嘟嘟嘟




嗯。




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. 设置navigationbar透明度时的坑

    1.需要设置导航条透明度时     UIImage *image = [UIImage imageNamed:@"bg_clear.png"]; //设置背景颜色 [nav2.na ...

  2. Java 使用new Thread和线程池的区别

    本文转至:https://www.cnblogs.com/cnmenglang/p/6273761.html , 孟凡柱的专栏 的博客,在此谢谢博主! 1.new Thread的弊端执行一个异步任务你 ...

  3. K:Treap(堆树)

      Treap=Tree+Heap.Treap是一棵二叉排序树,它的左子树和右子树分别是一个Treap,和一般的二叉排序树不同的是, Treap记录一个额外的数据, 就是优先级.Treap在以关键码构 ...

  4. mac,macbook 连接蓝牙耳机播放音乐断断续续

    个人的情况是, mac本连的网线,用的无线鼠标, 屋里80多号人都在用笔记本,应该也有好多开着无线的东西 解决方法: mac 或macbook 连接蓝牙耳机播放音乐断断续续的原因, 在网上找了好多方法 ...

  5. c#中表达式的返回值是啥?

    今天在学javascript的时候发现它其中有一个语法是这样的(a="haha).length;这样也能够输出haha这个字符串的长度,然而我在使用c#的时候分行读取txt文本的时候也用这个 ...

  6. 线上Bug修复流程

  7. animation 秒简单笔记

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 浏览器根对象navigator之客户端检测

    Navigator的5个主要属性: appName:Web浏览器的名称 appVersion:浏览器的版本号和其他版本信息 userAgent:浏览器在它的USER-AGENT HTTP标题中发送的字 ...

  9. CentOS7.4 + Hadoop2.9安装配置管理(分布式)

    1.  规划 1.1.  机器列表 NameNode SecondaryNameNode DataNodes 192.168.1.121 192.168.1.122 192.168.1.101 192 ...

  10. xcrun: error: invalid active developer path (/Applications/Xcode.app/Contents/Developer)解决办法

    背景 mac下卸载了xcode,使用git等命令时就提示错误.invalid active path(Applications/Xcode.app/Contents/Developer),这种情况可以 ...