本是打算研究后缀结构,但是发现不管是倍增还是DC3都异常容易错,知道最近才学习到了倍增算法的简易写法,但是仍然不爽,于是乎进入了后缀平衡树这样一个大坑。
风雨,残花,遇见你
首先遇到的一个问题就是treap常数太大,虽然网上的裸题可以过,但是却异常的缓慢。。。。
以bzoj3682为例
用treap解决为2400ms
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
----------
template<class T>inline void read(T &res){
static char ch;T flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;res*=flag;
}
#define N 500010
#define LL long long
int n,m,len,type,lastans,x,y;
int ch[N][2],rd[N],cl[N],cnt,root;
LL rk[N];
inline int randlmy(){
static int seed=173;
return seed=int(seed*48271LL%2147483647);
}
int cmp(int x,int y){
return cl[x]<cl[y]||(cl[x]==cl[y]&&rk[x-1]<rk[y-1]);
}
void rebuild(int &rt,LL l,LL r){
if(!rt)return;
rk[rt]=l+r;
LL mid=(l+r)>>1;
rebuild(ch[rt][0],l,mid);
rebuild(ch[rt][1],mid,r);
}
void rotate(int &p,int d,LL l,LL r){
int q=ch[p][d^1];
ch[p][d^1]=ch[q][d];
ch[q][d]=p;
p=q;
rebuild(p,l,r);
}
void insert(int &rt,LL l,LL r){
LL mid=(r+l)>>1;
if(!rt){rt=cnt;rk[rt]=l+r;return;}
if(cmp(cnt,rt)){insert(ch[rt][0],l,mid);if(rd[ch[rt][0]]>rd[rt])rotate(rt,1,l,r);}
else{insert(ch[rt][1],mid,r);if(rd[ch[rt][1]]>rd[rt])rotate(rt,0,l,r);}
}
void insert(int v){
cl[++cnt]=v;
rd[cnt]=randlmy()*randlmy();
insert(root,1,1LL<<61);
}
#define R(rt) rt<<1|1
#define L(rt) rt<<1
int minn[N<<2