• BZOJ 1014: [JSOI2008]火星人prefix


    Sol

    Splay+Hash+二分答案.

    用Splay维护Hash,二分答案判断.

    复杂度 (O(nlog^2n))

    PS:这题调了两个晚上因为没开long long.许久不写数据结构题感觉写完整个人都不好了...

    感觉还是应该经常开几道数据结构题来毒自己.

    Code

    /**************************************************************
        Problem: 1014
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:6580 ms
        Memory:9320 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
     
    typedef unsigned long long LL;
    const int N = 200050;
    #define lc(o) d[o].ch[0]
    #define rc(o) d[o].ch[1]
    #define f(o) d[o].f
    #define h(o) d[o].h
    #define v(o) d[o].v
    #define s(o) d[o].s
    #define mid ((l+r)>>1)
     
    //char *ps=(char *)malloc(N<<3);
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
     
    LL p[N];char ch[N];
    struct SplayTree{
        struct Node{
            int ch[2],f;
            LL h,v;int s;
            void Init(LL hh,LL vv,int ss){ h=hh,v=vv,s=ss,ch[0]=ch[1]=f=0; }
        }d[N];
        int rt,cnt;
         
        void PushUp(int o){
            if(!o) return;
            d[o].h=0;d[o].s=d[lc(o)].s+d[rc(o)].s+1;
            h(o)=(LL)h(lc(o))+v(o)*p[s(lc(o))]+h(rc(o))*p[s(lc(o))+1];
    //      if(rc(o)!=0) h(o)=h(o)+h(rc(o));
    //      h(o)=h(o)+v(o)*p[d[rc(o)].s];
    //      if(lc(o)!=0) h(o)=h(o)+h(lc(o))*p[d[rc(o)].s+1];
        }
        void Build(int &o,int fa,int l,int r){
            if(l>r) return;
            o=++cnt;
            d[o].Init(0,0,0);
            if(ch[mid]>='a') d[o].v=ch[mid]-'a'+13;
            f(o)=fa;
            Build(lc(o),o,l,mid-1);
            Build(rc(o),o,mid+1,r);
            PushUp(o);
        }
    //  int Build(int l,int r,int fa){
    //      if(l==r){
    //          d[l].Init(0,0,0);
    //          if(ch[l]>='a') d[l].v=d[l].h=ch[l]-'a'+1;
    //          d[l].s=1,f(l)=fa,PushUp(l);return l;
    //      }
    //      d[mid].Init(0,0,0);
    //      if(ch[mid]>='a') v(mid)=ch[mid]-'a'+1;f(mid)=fa;
    //      if(l<mid) lc(mid)=Build(l,mid-1,mid);
    //      if(r>mid) rc(mid)=Build(mid+1,r,mid);
    //      PushUp(mid);return mid;
    //  }
        void Rot(int o){
            int p=f(o),k=f(p),r=rc(p)==o;
            if(k) d[k].ch[rc(k)==p]=o;
            d[d[o].ch[r^1]].f=p,d[o].f=k;
            d[p].ch[r]=d[o].ch[r^1],d[o].ch[r^1]=p,d[p].f=o;
            PushUp(p),PushUp(o);
        }
        void DFS(int o){
            if(lc(o)) DFS(lc(o));
            cout<<o<<" "<<d[o].v<<" "<<d[o].h<<" "<<d[o].s<<endl;
            cout<<" lc="<<lc(o)<<" rc="<<rc(o)<<" f="<<f(o)<<endl;
            if(rc(o)) DFS(rc(o));
        }
        void Splay(int o,int g){
            for(;f(o)!=g;){
                int p=f(o),k=f(p);
                if(k!=g) Rot((rc(p)==o)==(rc(k)==p)?p:o);
    //          cout<<"Ok Rot"<<endl;
                Rot(o);
            }if(!g) rt=o;
    //      cout<<"rt="<<rt<<endl;
    //      DFS(rt);
        }
        int findkth(int o,int k){
            if(d[lc(o)].s>=k) return findkth(lc(o),k);
            else if(d[lc(o)].s+1<k) return findkth(rc(o),k-d[lc(o)].s-1);
            else return o;
        }
        void Insert(int x,LL v){
            int p=findkth(rt,x),q=findkth(rt,x+1);
            Splay(p,0),Splay(q,p);
    //      d[++cnt].Init(0,v,0);rt=cnt;
    //      rc(p)=0,f(p)=f(q)=rt,lc(rt)=p,rc(rt)=q;
    //      PushUp(p),PushUp(q),PushUp(rt);
            d[++cnt].Init(0,v,0);
            f(cnt)=q,lc(q)=cnt;
            PushUp(cnt),PushUp(q),PushUp(p);
        }
        void Change(int x,LL v){
            int o=findkth(rt,x);
            Splay(o,0),d[o].v=v,PushUp(o);
        }
        void init(){
    //      fread(ps,1,N<<3,stdin);
            p[0]=1;for(int i=1;i<N;i++) p[i]=(LL)p[i-1]*197; 
            d[0].Init(0,0,0);
            scanf("%s",ch+2);int n=strlen(ch+2);
            Build(rt,0,1,n+2);
    //      rt=Build(1,n+2,0);
    //      cout<<rt<<" "<<cnt<<endl;
        }
        LL Query(int u,int v){
    //      if(u>v) return -1;
            u--,v++;
            u=findkth(rt,u),v=findkth(rt,v);
    //      cout<<"Ok find "<<u<<" "<<v<<endl;
            Splay(u,0),Splay(v,u);
    //      cout<<"Ok Splay"<<endl;
            return h(lc(v));
        }
        void sol(){
            char opt[5],c[5];int u,v;
            for(int m=in();m--;){
                scanf("%s",opt);
    //          cout<<opt<<"********"<<endl;
                if(opt[0]=='R') scanf("%d%s",&u,c),Change(u+1,c[0]-'a'+13);
                else if(opt[0]=='I') scanf("%d%s",&u,c),Insert(u+1,c[0]-'a'+13);
                else {
                    u=in()+1,v=in()+1;
                    int l=0,r=min(cnt-v,cnt-u);
    //              cout<<"Start Q"<<endl<<"*********"<<endl;
                    while(l<=r){
    //                  cout<<"***
    cs mid="<<mid<<endl;
    //                  cout<<u<<" "<<mid<<" "<<Query(u,u+mid-1)<<endl;
    //                  cout<<v<<" "<<mid<<" "<<Query(v,v+mid-1)<<endl;
                        if((LL)Query(u,u+mid-1)==Query(v,v+mid-1)) l=mid+1;
                        else r=mid-1;
                    }printf("%d
    ",r);
                }
    //          cout<<opt<<" is ok"<<endl;
            }
        }
    }spl;
     
    int main(){
    //  freopen("in.in","r",stdin);
    //  freopen("out.out","w",stdout);
        spl.init();
    //  cout<<"Finish init()"<<endl;
    //  spl.DFS(spl.rt);
    //  cout<<"Finish DFS()"<<endl;
        spl.sol();
    //  cout<<"Finish sol()"<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    ACM成长之路
    洛谷P1047 校门外的树
    洛谷P1046 陶陶摘苹果
    2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F题
    图论:POJ2186-Popular Cows (求强连通分量)
    DFS:POJ1562-Oil Deposits(求连通块个数)
    DFS:POJ3620-Avoid The Lakes(求最基本的联通块)
    map函数的应用:UVa156-Ananagrams
    set的应用:UVa10815-Andy's First Dictionary
    水题:UVa253-Cube painting
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5886617.html
Copyright © 2020-2023  润新知