• bzoj1014 [JSOI2008]火星人prefix


    bzoj1014 [JSOI2008]火星人prefix


    原题链接


    题解

    平衡树维护字符串。
    至于LCP二分+哈希
    (hash[i]=hash[ls]+ch×base^{ls->size}+hash[rs]×base^{ls->size+1})


    Code

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define Fname "bzoj_1014"
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    #define fir first
    #define sec second
    #define pr pair<point,point>
    #define mp make_pair
    typedef unsigned int ll;
    il int gi(){
        rg int x=0;rg char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x;
    }
    typedef struct node* point;
    point null;
    int seed=2333;
    il int Rand(){return seed=seed*19260817ll%2147483647;}
    const int maxn=1e5+2;
    ll base[maxn],Base[maxn];
    struct node{
        int size,rand,ch;
        ll h,H;
        point ls,rs;
        node(char _ch){
    	ch=_ch-'`',rand=Rand(),size=1,ls=rs=null;
    	h=H=ch;
        }
        il vd reset(){
    	size=ls->size+rs->size+1;
    	h=ls->h+base[ls->size]*ch+base[ls->size+1]*rs->h;
    	H=ls->H+Base[ls->size]*ch+Base[ls->size+1]*rs->H;
        }
    };
    point root;
    il point build(){
        char str[100010];
        scanf("%s",str+1);
        int n=strlen(str+1);
        point now,stk[n+2],lst;int top=0;
        rep(i,1,n){
    	now=new node(str[i]),lst=null;
    	while(top&&stk[top]->rand>now->rand)lst=stk[top],stk[top--]->reset();
    	if(top)stk[top]->rs=now;
    	now->ls=lst,stk[++top]=now;
        }
        while(top)stk[top--]->reset();
        return stk[1];
    }
    il point merge(point a,point b){
        if(a==null){b->reset();return b;}
        if(b==null){a->reset();return a;}
        if(a->rand<b->rand){a->rs=merge(a->rs,b);a->reset();return a;}
        else{b->ls=merge(a,b->ls);b->reset();return b;}
    }
    il pr split(point now,int num){
        if(now==null)return mp(null,null);
        point ls=now->ls,rs=now->rs;
        if(num==now->ls->size){now->ls=null,now->reset();return mp(ls,now);}
        if(num==now->ls->size+1){now->rs=null,now->reset();return mp(now,rs);}
        if(now->ls->size>num){
    	pr T=split(now->ls,num);
    	now->ls=T.sec,now->reset();
    	return mp(T.fir,now);
        }else{
    	pr T=split(now->rs,num-now->ls->size-1);
    	now->rs=T.fir,now->reset();
    	return mp(now,T.sec);
        }
    }
    il vd Get(char&ch){do ch=getchar();while(ch<'a'||ch>'z');}
    il vd change(){
        int k=gi();char ch;Get(ch);
        pr T=split(root,k-1),TT=split(T.sec,1);
        TT.fir->ch=TT.fir->h=TT.fir->H=ch-'`';
        root=merge(T.fir,merge(TT.fir,TT.sec));
    }
    il vd ins(){
        int k=gi();char ch;Get(ch);
        pr T=split(root,k);
        root=merge(T.fir,merge(new node(ch),T.sec));
    }
    il pair<ll,ll>GetHash(int l,int r){
        pair<ll,ll>ret;
        pr T=split(root,l-1),TT=split(T.sec,r-l+1);
        ret=mp(TT.fir->h,TT.fir->H);
        root=merge(T.fir,merge(TT.fir,TT.sec));
        return ret;
    }
    il bool check(int&x,int&y,int mid){
        pair<ll,ll>a=GetHash(x,x+mid-1),b=GetHash(y,y+mid-1);
        return a.fir==b.fir&&a.sec==b.sec;
    }
    il vd solve(){
        int x=gi(),y=gi();
        int mid,l=0,r=min(root->size-x+1,root->size-y+1);
        while(l<r){
    	mid=(l+r)>>1;
    	if(check(x,y,mid+1))l=mid+1;
    	else r=mid;
        }printf("%d
    ",l);
    }
    int main(){
        freopen(Fname".in","r",stdin);
        freopen(Fname".out","w",stdout);
        null=new node('`');
        null->size=0;
        null->ls=null->rs=null;
        base[0]=1;
        rep(i,1,1e5)base[i]=base[i-1]*29;
        Base[0]=1;
        rep(i,1,1e5)Base[i]=Base[i-1]*23333;
        root=build();
        int m=gi();char opt;
        while(m--){
    	do opt=getchar();while(opt<'A'||opt>'Z');
    	if(opt=='Q')solve();
    	else if(opt=='R')change();
    	else ins();
        }
        return 0;
    }
    

    一个hash快些

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define Fname "bzoj_1014"
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    #define fir first
    #define sec second
    #define pr pair<point,point>
    #define mp make_pair
    typedef unsigned int ll;
    il int gi(){
        rg int x=0;rg char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x;
    }
    typedef struct node* point;
    point null;
    int seed=2333;
    il int Rand(){return seed=seed*19260817ll%2147483647;}
    const int maxn=1e5+2;
    ll base[maxn];
    struct node{
        int size,rand,ch;
        ll h;
        point ls,rs;
        node(char _ch){
    	ch=_ch-'`',rand=Rand(),size=1,ls=rs=null;
    	h=ch;
        }
        il vd reset(){
    	size=ls->size+rs->size+1;
    	h=ls->h+base[ls->size]*ch+base[ls->size+1]*rs->h;
        }
    };
    point root;
    il point build(){
        char str[100010];
        scanf("%s",str+1);
        int n=strlen(str+1);
        point now,stk[n+2],lst;int top=0;
        rep(i,1,n){
    	now=new node(str[i]),lst=null;
    	while(top&&stk[top]->rand>now->rand)lst=stk[top],stk[top--]->reset();
    	if(top)stk[top]->rs=now;
    	now->ls=lst,stk[++top]=now;
        }
        while(top)stk[top--]->reset();
        return stk[1];
    }
    il point merge(point a,point b){
        if(a==null){b->reset();return b;}
        if(b==null){a->reset();return a;}
        if(a->rand<b->rand){a->rs=merge(a->rs,b);a->reset();return a;}
        else{b->ls=merge(a,b->ls);b->reset();return b;}
    }
    il pr split(point now,int num){
        if(now==null)return mp(null,null);
        point ls=now->ls,rs=now->rs;
        if(num==now->ls->size){now->ls=null,now->reset();return mp(ls,now);}
        if(num==now->ls->size+1){now->rs=null,now->reset();return mp(now,rs);}
        if(now->ls->size>num){
    	pr T=split(now->ls,num);
    	now->ls=T.sec,now->reset();
    	return mp(T.fir,now);
        }else{
    	pr T=split(now->rs,num-now->ls->size-1);
    	now->rs=T.fir,now->reset();
    	return mp(now,T.sec);
        }
    }
    il vd Get(char&ch){do ch=getchar();while(ch<'a'||ch>'z');}
    il vd change(){
        int k=gi();char ch;Get(ch);
        pr T=split(root,k-1),TT=split(T.sec,1);
        TT.fir->ch=TT.fir->h=ch-'`';
        root=merge(T.fir,merge(TT.fir,TT.sec));
    }
    il vd ins(){
        int k=gi();char ch;Get(ch);
        pr T=split(root,k);
        root=merge(T.fir,merge(new node(ch),T.sec));
    }
    il ll GetHash(int l,int r){
        ll ret;
        pr T=split(root,l-1),TT=split(T.sec,r-l+1);
        ret=TT.fir->h;
        root=merge(T.fir,merge(TT.fir,TT.sec));
        return ret;
    }
    il bool check(int&x,int&y,int mid){
        ll a=GetHash(x,x+mid-1),b=GetHash(y,y+mid-1);
        return a==b;
    }
    il vd solve(){
        int x=gi(),y=gi();
        int mid,l=0,r=min(root->size-x+1,root->size-y+1);
        while(l<r){
    	mid=(l+r)>>1;
    	if(check(x,y,mid+1))l=mid+1;
    	else r=mid;
        }printf("%d
    ",l);
    }
    int main(){
        freopen(Fname".in","r",stdin);
        freopen(Fname".out","w",stdout);
        null=new node('`');
        null->size=0;
        null->ls=null->rs=null;
        base[0]=1;
        rep(i,1,1e5)base[i]=base[i-1]*29;
        root=build();
        int m=gi();char opt;
        while(m--){
    	do opt=getchar();while(opt<'A'||opt>'Z');
    	if(opt=='Q')solve();
    	else if(opt=='R')change();
    	else ins();
        }
        return 0;
    }
    
    博主是蒟蒻,有问题请指出,谢谢!
    本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。
  • 相关阅读:
    C++——STL内存清除
    c++——智能指针学习(unique_ptr)
    linux下将tomcat加入服务
    linux下oracle远程连接的问题
    oracle计算容量的方式
    oracle删除表的方式
    阻塞与非阻塞的区别
    java中queue的使用
    yum源
    VMware Tools 安装
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7489297.html
Copyright © 2020-2023  润新知