zoukankan      html  css  js  c++  java
  • 【BZOJ1014】火星人(Splay,哈希)

    【BZOJ1014】火星人(Splay,哈希)

    题面

    BZOJ

    题解

    要动态维护这个串,一脸的平衡树。
    那么用(Splay)维护这个哈希值就好了。
    每次计算答案的时候二分+Splay计算区间哈希值,
    时间复杂度(O(nlog^2n))

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ull unsigned long long
    #define ll long long
    #define RG register
    #define MAX 111111
    #define ls (t[x].ch[0])
    #define rs (t[x].ch[1])
    const int base=2333;
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    char ch[MAX];
    ull pw[MAX];
    int root,tot;
    struct Node
    {
    	int ch[2],ff,size,len;
    	ull v,Hash;
    }t[MAX];
    void pushup(int x)
    {
    	t[x].size=t[ls].size+t[rs].size+1;
    	t[x].len=t[ls].len+t[rs].len+(x>2);
    	t[x].Hash=(t[ls].Hash*base+t[x].v)*pw[t[rs].len]+t[rs].Hash;
    }
    void rotate(int x)
    {
    	int y=t[x].ff,z=t[y].ff;
    	int k=t[y].ch[1]==x;
    	t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
    	t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
    	t[x].ch[k^1]=y;t[y].ff=x;
    	pushup(y);
    }
    void Splay(int x,int goal)
    {
    	while(t[x].ff!=goal)
    	{
    		int y=t[x].ff,z=t[y].ff;
    		if(z!=goal)
    			(t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(!goal)root=x;pushup(x);
    }
    int Kth(int k)
    {
    	int x=root;
    	while(233)
    	{
    		if(t[ls].size+1==k)return x;
    		if(t[ls].size+1<k)k-=t[ls].size+1,x=rs;
    		else x=ls;
    	}
    }
    ull Hash(int l,int len)
    {
    	int L=Kth(l),R=Kth(l+len+1);
    	Splay(L,0);Splay(R,L);
    	return t[t[R].ch[0]].Hash;
    }
    int LCQ(int x,int y)
    {
    	int l=0,r=tot-max(x,y)-1,ret=0;
    	while(l<=r)
    	{
    		int mid=(l+r)>>1;
    		if(Hash(x,mid)==Hash(y,mid))l=mid+1,ret=mid;
    		else r=mid-1;
    	}
    	return ret;
    }
    void insert(int x,int v)
    {
    	int L=Kth(x+1),R=Kth(x+2);
    	Splay(L,0);Splay(R,L);
    	t[++tot].v=v;t[R].ch[0]=tot;
    	t[tot].ff=R;Splay(tot,0);
    }
    void Modify(int x,int v)
    {
    	int L=Kth(x),R=Kth(x+2);
    	Splay(L,0);Splay(R,L);
    	t[t[R].ch[0]].v=v;pushup(t[R].ch[0]);
    	pushup(R);pushup(L);
    }
    int main()
    {
    	pw[0]=1;for(int i=1;i<MAX;++i)pw[i]=pw[i-1]*base;
    	scanf("%s",ch+1);
    	t[1].ch[1]=2;t[2].ff=1;tot=2;root=1;pushup(2);pushup(1);
    	for(int i=1,l=strlen(ch+1);i<=l;++i)insert(i-1,ch[i]);
    	int Q=read(),x,y;
    	while(Q--)
    	{
    		scanf("%s",ch);
    		if(ch[0]=='Q')printf("%d
    ",LCQ(read(),read()));
    		else if(ch[0]=='R'){x=read();scanf("%s",ch);y=ch[0];Modify(x,y);}
    		else{x=read();scanf("%s",ch);y=ch[0];insert(x,y);}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Vue项目端口号占用
    理解vuex -- vue的状态管理模式
    2018-7-10杂记
    JS 数组操作总结
    JS 字符串操作总结
    【javascript练习题】函数
    【javascript练习题】this指针和作用域
    canal实时同步mysql binlog到rabbitmq
    Hexo+GitHub+Netlify一站式搭建属于自己的博客网站
    Git学习原版手稿
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9246507.html
Copyright © 2011-2022 走看看