[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, 我们 ...
随机推荐
- SpringBoot+Mybatis整合入门(一)
SpringBoot+Mybatis 四步整合 第一步 添加依赖 springBoot+Mybatis相关依赖 <!--springBoot相关--> <parent> < ...
- Java计算两个经纬度间的距离最简单的方式
开发中经常会遇到计算两个点(经纬度)之间的距离或者计算最近门店的场景,下面简单实现一下如何计算两个经纬度之间相隔的距离. 1.导入geodesy的maven依赖 或者到阿里云maven仓库下载jar包 ...
- Java基础——JDBC
今天学习的内容是:JDBC 通常jdbc连接分6步: 1)注册驱动: 2)建立连接: 3)创建Statement: 4)执行sql 语句: 5)处理结果集(若sql 语句为查询语句): 6)关闭连接. ...
- 谷歌浏览器network请求时间(stalled,DNS Lookup,Waiting)分析以及解决方案
network工具功能强大,能够让我看到网页加载的信息,比如加载时间,和先后顺序,是否是并行加载,还是堵塞加载. 默认情况下有八列: (1).Name:表示加载的文件名. (2).Method:表示请 ...
- BZOJ2663 [Beijing wc2012]灵魂宝石
Description 平面中有\(n\)个黑点和\(n\)个白点.这些点组成\(n\)对,但是你不知道它们的对应关系.若某队中黑点白点距离\(<R\),则它是好的:\(>R\)则不是好的 ...
- 转:nginx 官方drupal 配置 - Drupal | NGINX
#参考:nginx 官方drupal 配置 - Drupal | NGINX server { server_name example.com; root /var/www/drupal8; ## & ...
- 使用display:none和visibility:hidden隐藏的区别
今天做毕设时遇到了一个小问题,我做了一个tab导航栏,点击一个tab页其它tab页隐藏,这时候第一想法是使用display:none来控制显示隐藏,写了之后发现使用display会有一个问题,就是第二 ...
- 纯css修改复选框默认样式
input[type='checkbox']{ width: 20px; height: 20px; background-color: #fff; -webkit-appearance:none; ...
- 网络基础 图解Windows系统下单网卡设置双IP访问不同网段的方法
图解Windows系统下单网卡设置双IP访问不同网段的方法 by:授客 QQ:1033553122 在Windows系统下即使只有一块网卡,同样可以实现双IP访问不同网段. 例: 外网信息: IP:1 ...
- 初次使用git就遭遇不测,提示没有这个服务连接和需要配置git的一个http参数 NO network connection,SSl host could not be verified ...
第一次使用git 拉取服务上的项目到本地,结果,在拿到访问的url地址后,输入用户名密码,失败了. --eclispe 4.5.3 继承了git客户端插件的版本 ------下一步后,报错 NO n ...