• P4036 [JSOI2008]火星人(splay+hash+二分)


    P4036 [JSOI2008]火星人

    Splay维护hash,查询二分

    $a[x].vl=a[lc].vl*ha[a[rc].sz+1]+a[x].w*ha[a[rc].sz]+a[rc].vl$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef unsigned long long ull;
    int read(){
        char c=getchar(); int x=0;
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') x=x*10+c-48,c=getchar();
        return x;
    }
    #define N 300005
    const int bas=13331;
    int n,Q; char q[N],q1[3]; ull ha[N];
    struct node{int ch[2],sz,fa; ull vl,w;}a[N];
    struct Splay{
        #define lc a[x].ch[0]
        #define rc a[x].ch[1]
        #define mid (l+r)/2
        int rt,u;
        inline void up(int x){
            a[x].sz=a[lc].sz+a[rc].sz+1,
            a[x].vl=a[lc].vl*ha[a[rc].sz+1]+a[x].w*ha[a[rc].sz]+a[rc].vl; 
        }
        inline int whi(int y,int x){return a[y].ch[1]==x;}
        void turn(int x,int &k){
            int y=a[x].fa,z=a[y].fa,l=whi(y,x),r=l^1;
            if(y==k) k=x;
            else a[z].ch[whi(z,y)]=x;
            a[a[x].ch[r]].fa=y; a[y].fa=x; a[x].fa=z;
            a[y].ch[l]=a[x].ch[r]; a[x].ch[r]=y;
            up(y); up(x);
        }
        void splay(int x,int &k){
            for(;x!=k;turn(x,k)){
                int y=a[x].fa,z=a[y].fa;
                if(y!=k) turn(whi(z,y)==whi(y,x)?y:x,k);
            }
        }
        int kth(int k){
            int x=rt;
            while(a[lc].sz+1!=k){
                if(a[lc].sz>=k) x=lc;
                else k=k-a[lc].sz-1,x=rc;
            }return x;
        }
        inline void rep(int x,ull k){a[x=kth(x)].w=k,splay(x,rt);}
        void ins(int x,ull k){
            x=kth(x); ++u;
            if(!rc) rc=u;
            else{for(x=rc;lc;x=lc); lc=u;}
            a[u].fa=x; a[u].w=k; up(u); splay(u,rt);
        }
        ull Fi(int x,int y){
            int L=kth(x-1),R=kth(y+1);
            splay(L,rt); splay(R,a[L].ch[1]);
            return a[a[R].ch[0]].vl;
        }
        int ask(int x,int y){
            if(x>y) swap(x,y);
            int l=1,r=u-y,re=0;
            while(l<=r){
                if(Fi(x,x+mid-1)!=Fi(y,y+mid-1)) r=mid-1;
                else re=mid,l=mid+1;
            }return re;
        }
        int build(int Fa,int l,int r){
            a[mid].w=(ull)q[mid-1]; a[mid].fa=Fa; ++u;
            if(l<mid) a[mid].ch[0]=build(mid,l,mid-1);
            if(r>mid) a[mid].ch[1]=build(mid,mid+1,r);
            up(mid); return mid;
        }
    }S;
    int main(){
        scanf("%s",q+1); n=strlen(q+1); ha[0]=1;
        for(int i=1;i<N;++i) ha[i]=ha[i-1]*bas;
        S.rt=S.build(0,1,n+2); Q=read();//建树时记得加入边界
        for(int i=1,w1,w2;i<=Q;++i){
            scanf("%s",q1);
            if(q1[0]=='Q') w1=read(),w2=read(),printf("%d
    ",S.ask(w1+1,w2+1));
            if(q1[0]=='R') w1=read(),scanf("%s",q1),S.rep(w1+1,(ull)q1[0]);
            if(q1[0]=='I') w1=read(),scanf("%s",q1),S.ins(w1+1,(ull)q1[0]);
        }return 0;
    }
  • 相关阅读:
    Linux:修改Shell命令提示符及颜色
    Linux:cut命令详解
    pageadmin去掉xxx
    高手详解SQL性能优化十条经验
    一道简单递归题
    list<?>转换成 对应的 class
    《一道笔试题》找出最连续数字的最大长度
    poi 获取excel数据 导入数据库
    有一个5ml 的瓶子 和3ml 的瓶子 和 很多水 现在 要取出4ml的水 请写出编程 多种解法
    假设字符串类似这样的aba和aab,abc和bca就相等,现在随便给你二组字符串,请编程比较他们看是否相等
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/11443071.html
Copyright © 2020-2023  润新知