UVA - 11996 可持久化Treap 维护Hash Ver.2
这回总算是过了..
4600ms+,服务器抖一抖又没了
对于极端卡时间的情况还是考虑屈服于Splay吧
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iin(a) scanf("%d",&a)
#define lin(a) scanf("%lld",&a)
#define din(a) scanf("%lf",&a)
#define s0(a) scanf("%s",a)
#define s1(a) scanf("%s",a+1)
#define print(a) printf("%lld",(ll)a)
#define enter putchar('\n')
#define blank putchar(' ')
#define println(a) printf("%lld\n",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int MAXN = 4e5+11;
const double EPS = 1e-7;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 1e9+7;
unsigned int SEED = 17;
const ll INF = 1ll<<60;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline int Rand(){
SEED=SEED*1103515245+12345;
return SEED/65536;
}
ull p[MAXN];
int curlen;
struct Treap{
int son[MAXN][2],root,tot;
int val[MAXN],fix[MAXN],size[MAXN];
bool flip[MAXN];
ull Hash[MAXN][2];
int stk[MAXN];
#define lc son[o][0]
#define rc son[o][1]
void init(){
root=0;
son[0][0]=son[0][1]=0;
val[0]=fix[0]=size[0]=0;
flip[0]=0;
Hash[0][0]=Hash[0][1]=0;
tot=1;
}
int node(int v){
son[tot][0]=son[tot][1]=0;
val[tot]=v; fix[tot]=Rand();
size[tot]=1;flip[tot]=0;
Hash[tot][0]=Hash[tot][1]=v;
return tot++;
}
void pu(int o){
size[o]=size[lc]+size[rc]+1;
Hash[o][0]=Hash[rc][0]+val[o]*p[size[rc]]+Hash[lc][0]*p[size[rc]+1];
Hash[o][1]=Hash[lc][1]+val[o]*p[size[lc]]+Hash[rc][1]*p[size[lc]+1];
}
void rev(int o){
swap(Hash[o][0],Hash[o][1]);
swap(lc,rc);
flip[o]^=1;
}
void pd(int o){
if(flip[o]){
if(lc) rev(lc);
if(rc) rev(rc);
flip[o]=0;
}
}
void split(int o,int k,int &a,int &b){
if(!o){
a=b=0;
return;
}else if(k<=size[lc]){
pd(o);
b=o;
split(lc,k,a,lc);
pu(o);
}else{
pd(o);
a=o;
split(rc,k-size[lc]-1,rc,b);
pu(o);
}
}
int merge(int a,int b){
if(!a) return b;
if(!b) return a;
if(a) pd(a); if(b) pd(b);
if(fix[a]<fix[b]){
son[a][1]=merge(son[a][1],b);
pu(a);
return a;
}else{
son[b][0]=merge(a,son[b][0]);
pu(b);
return b;
}
}
void insert(int pos,int v){
int a,b,t=node(v);
split(root,pos,a,b);
root=merge(merge(a,t),b);
}
int get(int pos){
int a,b,x,y;
split(root,pos-1,a,b);
split(b,1,x,y);
int t=x;
root=merge(a,merge(x,y));
return t;
}
void del(int pos){
int a,b,x,y;
split(root,pos-1,a,b);
split(b,1,x,y);
root=merge(a,y);
}
void revv(int pos,int len){//[pos,pos+len-1]
int a,b,x,y;
split(root,pos-1,a,b);
split(b,len,x,y);
rev(x);
root=merge(a,merge(x,y));
}
ull get(int pos,int len){
int a,b,x,y;
split(root,pos-1,a,b);
split(b,len,x,y);
ull ans=Hash[x][0];
root=merge(a,merge(x,y));
return ans;
}
bool C(int mid,int st1,int st2){
if(mid==0)return 0;
if(st1==0||st2==0)return 0;
return get(st1/*-mid+1*/,mid)==get(st2/*-mid+1*/,mid);
}
ll LCP(int a,int b){
int l=1,r=curlen-b+1,mid;
while(l<r){
mid=l+(r-l+1)/2;
if(C(mid,a,b))l=mid;
else r=mid-1;
}
return C(l,a,b)?l:0;
}
int build(char str[],int n){
int x,last=0,top=0;
rep(i,1,n){
x=node((int)str[i]),last=0;
while(top&&fix[stk[top]]>stk[x]){
pu(stk[top]),last=stk[top];
stk[top--]=0;
}
if(top) son[stk[top]][1]=x;
son[x][0]=last;
stk[++top]=x;
}
while(top){
pu(stk[top--]);
}
return stk[1];
}
}tp;
char str[MAXN];
int main(){
p[0]=1;
rep(i,1,MAXN-1) p[i]=p[i-1]*233;
int n,m;
while(~scanf("%d%d",&n,&m)){
s1(str);
curlen=n;
tp.init();
rep(i,1,n){
tp.insert(i,(int)str[i]);
}
rep(i,1,m){
int op=read();
int a,b;
switch(op){
case 1:
a=read();
b=read();
tp.insert(a,b+'0');
curlen++;
break;
case 2:
a=read();
tp.del(a);
curlen--;
break;
case 3:
a=read();
b=read();
tp.revv(a,b-a+1);
break;
case 4:
a=read();
b=read();
println(tp.LCP(a,b));
break;
}
}
}
return 0;
}
UVA - 11996 可持久化Treap 维护Hash Ver.2的更多相关文章
- UVA - 11996 Jewel Magic (Treap+二分哈希)
维护一个01序列,一共四种操作: 1.插入一个数 2.删除一个数 3.反转一个区间 4.查询两个后缀的LCP 用Splay或者Treap都可以做,维护哈希值,二分求LCP即可. 注意反转序列的时候序列 ...
- Codeforces - 38G 可持久化Treap 区间操作
题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...
- UVa 11996 Jewel Magic (splay + Hash + 二分)
题意:给定一个长度为n的01串,你的任务是依次执行如表所示的m条指令: 1 p c 在第p个字符后插入字符,p = 0表示在整个字符串之前插入2 p 删除第p个字符,后面的字符往前移3 p1 p2反转 ...
- Jewel Magic UVA - 11996 || bzoj1014: [JSOI2008]火星人prefix
Jewel Magic UVA - 11996 这是一道用splay/非旋treap做的题(这里用的是非旋treap) 1/2/3是splay/非旋treap的常规操作.对于操作4,可以用哈希法求LC ...
- UVALive 6145 Version Controlled IDE(可持久化treap、rope)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- 【模板】可持久化文艺平衡树-可持久化treap
题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...
- 可持久化Treap
终于写了一次可持久化Treap,做的是可持久化序列的模板题. Treap Treap=Tree+Heap,是一个随机化的数据结构.它的每个节点至少有两个关键字,一个是我们要存储的\(val\),一个是 ...
- Codeforces - 675D 可持久化Treap 树形操作
题意:模拟二叉树的构造过程,给出\(n\)个节点,每次从根插入,小于当前节点转到左儿子,否则右儿子,输出第\([2,n]\)个节点的父亲的权值 直接手动模拟会被链式结构T掉 网上找了下发现二叉树的性质 ...
- 好久不见的博客咯!——没有可持久化的可持久化treap
每每想要去了解可持久化treap这个好写好调的东东,然后就发现网上只有一个人的——SymenYang的!在此我必须得把他批判一番——写方法不贴代码是什么心态!而且写出来的是有问题的呀!害人不浅! 好吧 ...
随机推荐
- c语言实践输出某个区间中不是3的倍数的偶数
OK,先审题,我们最后要输出的那些数是需要满足两个条件的,第一个条件是,这个数不是3的倍数,第二个条件是这个数是偶数.也就是这样的数需要同时满足这两个条件的时候才把这个数输出. 不是3的倍数这个条件在 ...
- Examining Application Startup in ASP.NET 5
By Steve Smith June 23, 2015 ASP.NET 5 differs from previous versions of ASP.NET in many ways. Gone ...
- (转)Expression 表达式树学习整理
原文地址:http://www.cnblogs.com/li-peng/p/3154381.html 整理了一下表达式树的一些东西,入门足够了 先从ConstantExpression 开始一步一步的 ...
- Oracle 写存储过程的一个模板还有一些基本的知识点
我很少用Oracle,也算新手,不过其实入手没有那么难,下面只是一个基本知识,高手绕道,其实数据库基本是相同的,这里提供都是基本知识点 有一个Oracle溢出的问题,容易让新手怀疑到无所怀疑,其实就是 ...
- 转Delphi中XLSReadWrite控件的使用(1)---简介
XLSReadWrite控件简介: 一个你需要的,能在Delphi和.NET下访问Excel文件的完美解决方案. 一个经典的读写Excel的控件,对于使用Excel 开发很有帮助 官方网站: http ...
- 简单工厂(Simple Factory)模式
工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类.工厂模式有以下几种形态: 简单工厂(Simple Factory)模式 工厂方法(F ...
- Oracle排序函數Rank
出口給報關行出貨的時候,同一票shipment中合併多個invoice跟packing,轉出到廠商的報關系統時候,出口報關的序號會將invoice的序號做自動增加. 因為wafer會有出口給其他外包做 ...
- Xamarin.Forms之UserDialogs 重制版本
在 forms 里面,目前使用比较多的弹出组件是 Acr.UserDialogs ,但是这个组件有些小问题,比如 loading .hide 会同时把 toast 给一起关掉,android 下的 t ...
- 多态实现的原理------新标准c++程序设计
“多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...
- SKU:唯一标识填什么
策略 随意填写 只要别和别人重复就好 ,不过重复你也创建不了. 最好填与APP信息相关的,比如直接填写bundle ID 上去...跟套装ID保持一致. 你新建应用的时候都还没有APP ID 你怎么填 ...