BZOJ 1014: [JSOI2008]火星人prefix
Sol
Splay+Hash+二分答案.
用Splay维护Hash,二分答案判断.
复杂度 \(O(nlog^2n)\)
PS:这题调了两个晚上因为没开long long.许久不写数据结构题感觉写完整个人都不好了...
感觉还是应该经常开几道数据结构题来毒自己.
Code
/**************************************************************
Problem: 1014
User: BeiYu
Language: C++
Result: Accepted
Time:6580 ms
Memory:9320 kb
****************************************************************/ #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std; typedef unsigned long long LL;
const int N = 200050;
#define lc(o) d[o].ch[0]
#define rc(o) d[o].ch[1]
#define f(o) d[o].f
#define h(o) d[o].h
#define v(o) d[o].v
#define s(o) d[o].s
#define mid ((l+r)>>1) //char *ps=(char *)malloc(N<<3);
inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } LL p[N];char ch[N];
struct SplayTree{
struct Node{
int ch[2],f;
LL h,v;int s;
void Init(LL hh,LL vv,int ss){ h=hh,v=vv,s=ss,ch[0]=ch[1]=f=0; }
}d[N];
int rt,cnt; void PushUp(int o){
if(!o) return;
d[o].h=0;d[o].s=d[lc(o)].s+d[rc(o)].s+1;
h(o)=(LL)h(lc(o))+v(o)*p[s(lc(o))]+h(rc(o))*p[s(lc(o))+1];
// if(rc(o)!=0) h(o)=h(o)+h(rc(o));
// h(o)=h(o)+v(o)*p[d[rc(o)].s];
// if(lc(o)!=0) h(o)=h(o)+h(lc(o))*p[d[rc(o)].s+1];
}
void Build(int &o,int fa,int l,int r){
if(l>r) return;
o=++cnt;
d[o].Init(0,0,0);
if(ch[mid]>='a') d[o].v=ch[mid]-'a'+13;
f(o)=fa;
Build(lc(o),o,l,mid-1);
Build(rc(o),o,mid+1,r);
PushUp(o);
}
// int Build(int l,int r,int fa){
// if(l==r){
// d[l].Init(0,0,0);
// if(ch[l]>='a') d[l].v=d[l].h=ch[l]-'a'+1;
// d[l].s=1,f(l)=fa,PushUp(l);return l;
// }
// d[mid].Init(0,0,0);
// if(ch[mid]>='a') v(mid)=ch[mid]-'a'+1;f(mid)=fa;
// if(l<mid) lc(mid)=Build(l,mid-1,mid);
// if(r>mid) rc(mid)=Build(mid+1,r,mid);
// PushUp(mid);return mid;
// }
void Rot(int o){
int p=f(o),k=f(p),r=rc(p)==o;
if(k) d[k].ch[rc(k)==p]=o;
d[d[o].ch[r^1]].f=p,d[o].f=k;
d[p].ch[r]=d[o].ch[r^1],d[o].ch[r^1]=p,d[p].f=o;
PushUp(p),PushUp(o);
}
void DFS(int o){
if(lc(o)) DFS(lc(o));
cout<<o<<" "<<d[o].v<<" "<<d[o].h<<" "<<d[o].s<<endl;
cout<<" lc="<<lc(o)<<" rc="<<rc(o)<<" f="<<f(o)<<endl;
if(rc(o)) DFS(rc(o));
}
void Splay(int o,int g){
for(;f(o)!=g;){
int p=f(o),k=f(p);
if(k!=g) Rot((rc(p)==o)==(rc(k)==p)?p:o);
// cout<<"Ok Rot"<<endl;
Rot(o);
}if(!g) rt=o;
// cout<<"rt="<<rt<<endl;
// DFS(rt);
}
int findkth(int o,int k){
if(d[lc(o)].s>=k) return findkth(lc(o),k);
else if(d[lc(o)].s+1<k) return findkth(rc(o),k-d[lc(o)].s-1);
else return o;
}
void Insert(int x,LL v){
int p=findkth(rt,x),q=findkth(rt,x+1);
Splay(p,0),Splay(q,p);
// d[++cnt].Init(0,v,0);rt=cnt;
// rc(p)=0,f(p)=f(q)=rt,lc(rt)=p,rc(rt)=q;
// PushUp(p),PushUp(q),PushUp(rt);
d[++cnt].Init(0,v,0);
f(cnt)=q,lc(q)=cnt;
PushUp(cnt),PushUp(q),PushUp(p);
}
void Change(int x,LL v){
int o=findkth(rt,x);
Splay(o,0),d[o].v=v,PushUp(o);
}
void init(){
// fread(ps,1,N<<3,stdin);
p[0]=1;for(int i=1;i<N;i++) p[i]=(LL)p[i-1]*197;
d[0].Init(0,0,0);
scanf("%s",ch+2);int n=strlen(ch+2);
Build(rt,0,1,n+2);
// rt=Build(1,n+2,0);
// cout<<rt<<" "<<cnt<<endl;
}
LL Query(int u,int v){
// if(u>v) return -1;
u--,v++;
u=findkth(rt,u),v=findkth(rt,v);
// cout<<"Ok find "<<u<<" "<<v<<endl;
Splay(u,0),Splay(v,u);
// cout<<"Ok Splay"<<endl;
return h(lc(v));
}
void sol(){
char opt[5],c[5];int u,v;
for(int m=in();m--;){
scanf("%s",opt);
// cout<<opt<<"********"<<endl;
if(opt[0]=='R') scanf("%d%s",&u,c),Change(u+1,c[0]-'a'+13);
else if(opt[0]=='I') scanf("%d%s",&u,c),Insert(u+1,c[0]-'a'+13);
else {
u=in()+1,v=in()+1;
int l=0,r=min(cnt-v,cnt-u);
// cout<<"Start Q"<<endl<<"*********"<<endl;
while(l<=r){
// cout<<"***\ncs mid="<<mid<<endl;
// cout<<u<<" "<<mid<<" "<<Query(u,u+mid-1)<<endl;
// cout<<v<<" "<<mid<<" "<<Query(v,v+mid-1)<<endl;
if((LL)Query(u,u+mid-1)==Query(v,v+mid-1)) l=mid+1;
else r=mid-1;
}printf("%d\n",r);
}
// cout<<opt<<" is ok"<<endl;
}
}
}spl; int main(){
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
spl.init();
// cout<<"Finish init()"<<endl;
// spl.DFS(spl.rt);
// cout<<"Finish DFS()"<<endl;
spl.sol();
// cout<<"Finish sol()"<<endl;
return 0;
}
BZOJ 1014: [JSOI2008]火星人prefix的更多相关文章
- BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6243 Solved: 2007[Submit] ...
- BZOJ 1014: [JSOI2008]火星人prefix Splay+二分
1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...
- 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 + 二分)
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8112 Solved: 2569[Submit] ...
- [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】
题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...
- bzoj 1014 [JSOI2008]火星人prefix(splay+hash)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP ...
- bzoj 1014 [JSOI2008]火星人prefix——splay+哈希
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...
随机推荐
- Centos 6.0将光盘作为yum源的设置方法
在使用Centos 的时候,用yum来安装软件包是再方便不过了,但是如果在无法连接互联网的情况下,yum就不好用了. 下面介绍一种方式,就是将Centos安装光盘作为yum源,然后使用yum来安装软件 ...
- setTimeout不断重复执行
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. setTimeout(code,millisec) code 必需.要调用的函数后要执行的 JavaScript 代码串. ...
- DESCryptoServiceProvider
public static byte[] DESEncrypt(byte[] data, byte[] sKey) { return DESEncrypt(data, sKey, sKey); } / ...
- NopCommerce源码分析ContainerBuilder builder.Update(container)
/// <summary> /// Register dependencies /// </summary> /// <param name="config&q ...
- autofac + owin + webform + mvc + webapi集成demo
http://git.oschina.net/shiningrise/AutofacOwinDemo using Microsoft.Owin; using Owin; using System.We ...
- Nginx限制某个IP同一时间段的访问次数
nginx可以通过HttpLimitReqModul和HttpLimitZoneModule配置来限制ip在同一时间段的访问次数. HttpLimitReqModul用来限制连单位时间内连接数的模块, ...
- django_web代码更新
- StringUtils
StringUtils.hasText(字符串) 如果字符串里面的值为null, "", " ",那么返回值为false:否则为true
- oracle 的wm_concat函数使用
转载自:http://blog.itpub.net/post/42245/522757 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来 ...
- 【转】快速理解Kafka分布式消息队列框架
from:http://blog.csdn.net/colorant/article/details/12081909 快速理解Kafka分布式消息队列框架 标签: kafkamessage que ...