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的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)

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

  7. [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】

    题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...

  8. bzoj 1014 [JSOI2008]火星人prefix(splay+hash)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP ...

  9. bzoj 1014 [JSOI2008]火星人prefix——splay+哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...

随机推荐

  1. 10月23日上午PHP数组

    正则表达式 1.替换 $s = "hello5world"; $s = preg_replace("/\d/","#",$s); echo ...

  2. JavaWeb学习笔记——Ajax

  3. [Redis]通过代码配置Redis

    查看了文档https://azure.microsoft.com/en-us/documentation/articles/cache-how-to-scale/,发现可以使用代码来配置Redis,所 ...

  4. 重写UILabler的sizeThatFits方法,需要触发两次才会有效果

    #import "ViewController.h" @interface SpecialLabel:UILabel @end @implementation SpecialLab ...

  5. 序列化模块之 pickle 和 json

    用于序列化的两个模块: json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 Json模块提供了四个功能:dumps ...

  6. 第一篇随笔!!!THE FIRST BLOOD!!!

    注册成功,哈哈 以后就要在这扎窝了,要坚持记录下去,关于生活,关于学习. 选了个皮肤 darkgreen,不错,简洁舒服,喜欢. 好,差不多了,感觉没什么可说的了...==

  7. 抓取网站数据不再是难事了,Fizzler(So Easy)全能搞定

    首先从标题说起,为啥说抓取网站数据不再难(其实抓取网站数据有一定难度),SO EASY!!!使用Fizzler全搞定,我相信大多数人或公司应该都有抓取别人网站数据的经历,比如说我们博客园每次发表完文章 ...

  8. Mysql函数:Last_insert_id()语法讲解

    Mysql函数可以实现许多我们需要的功能,下面介绍的Mysql函数Last_insert_id()就是其中之一,希望对您学习Mysql函数能有所帮助. 自动返回最后一个INSERT或 UPDATE 查 ...

  9. step 4 GCD 队列演练

    串行队列 特点 以先进先出的方式,顺序调度队列中的任务执行 无论队列中所指定的执行任务函数是同步还是异步,都会等待前一个任务执行完成后,再调度后面的任务 队列创建 dispatch_queue_t q ...

  10. Linux下,telnet命令如何退出

    测试连接本地的memcached telnet 链接后是这样的: wangkongming@Vostro ~ $ telnet Trying 127.0.0.1... Connected to 127 ...