zoukankan      html  css  js  c++  java
  • Very Long Suffix Array

    题解:

    原来动态开点平衡树是O(n)空间的。。

    只需要在split的查找和出来之后动态开点就可以了

    这题的结论是2^(b[a[i]+1]>b[a[i+1]+1]的个数)

    前60分是普通的平衡树操作完之后再算

    满分是动态开点平衡树

    对于一个点内部的统计一下,边界上的特判一下

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    #define ll long long
    #define mid ((h+t)>>1)
    #define mep(x,y) memcpy(x,y,sizeof(y))
    namespace IO
    {
        char ss[1<<24],*A=ss,*B=ss;
        IL char gc()
        {
            return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
        }
        template<class T>void read(T &x)
        {
            rint f=1,c;while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
            while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
        }
        char sr[1<<24],z[20]; int C=-1,Z;
        template<class T>void wer(T x)
        {
            if (x<0) sr[++C]='-',x=-x; 
            while (z[++Z]=x%10+48,x/=10);
            while (sr[++C]=z[Z],--Z);
        }
        IL void wer1() {sr[++C]=' ';}
        IL void wer2() {sr[++C]='
    ';}
        template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;}
        template<class T>IL void mina(T &x,T y) { if (x>y) x=y;}
        template<class T>IL T MAX(T x,T y){ return x>y?x:y;}
        template<class T>IL T MIN(T x,T y){ return x<y?x:y;}
    }
    using namespace IO;
    const int N=9e5;
    int a[N],b[N],xl[N],cnt,dy[N],d[N],tmp;
    const int mo=1e9+7;
    struct re{
        int a,b,kk,d;
    }c[N],f[N],p[N],c1[N];
    int nq;
    struct phs{
        int fa[N],rs[N],ls[N],num[N],o[N],v[N],cnt,cnt3;
        bool rev[N],t[N];
        IL void updata(int x)
        {
            num[x]=num[ls[x]]+num[rs[x]]+o[x];
        }
        IL void down(int x)
        {
            if (rev[x])
            {
                swap(ls[ls[x]],rs[ls[x]]);
                swap(ls[rs[x]],rs[rs[x]]);
                rev[ls[x]]^=1; rev[rs[x]]^=1;
                t[ls[x]]^=1; t[rs[x]]^=1;
                rev[x]=0;
            } 
        }
        void rotate(int x,int y)
        {
            int f1=fa[x];
            if (y==1)
            {
                rs[f1]=ls[x];
                if (ls[x]) fa[ls[x]]=f1;
            } else
            {
                ls[f1]=rs[x];
                if (rs[x]) fa[rs[x]]=f1;
            }
            fa[x]=fa[f1];
            if (fa[f1])
            {
                if (ls[fa[f1]]==f1) ls[fa[f1]]=x; else rs[fa[f1]]=x;
            }
            fa[f1]=x;
            if (y==1) ls[x]=f1; else rs[x]=f1;
            updata(f1); updata(x);
        }
        void dfs(int x)
        {
            if (fa[x]) dfs(fa[x]);
            down(x);
        }
        IL void splay(int x,int y)
        {
            dfs(x);
            int f1=fa[x];
            while (f1!=y)
            {
                if (fa[f1]==y)
                  if (ls[f1]==x) rotate(x,2); else rotate(x,1);
                else 
                  if (ls[fa[f1]]==f1) 
                    if (ls[f1]==x) rotate(f1,2),rotate(x,2);
                    else rotate(x,1),rotate(x,2);
                  else if (rs[f1]==x) rotate(f1,1),rotate(x,1);
                    else rotate(x,2),rotate(x,1);
                f1=fa[x];
            }
        }
        IL int sc(int x,int y)
        {
            if (t[x])
            {
              o[++nq]=y; num[nq]=y; fa[nq]=x; v[nq]=v[x];
              ls[nq]=ls[x]; o[x]-=y;
              v[x]+=y; ls[x]=nq; t[nq]=t[x];
            } else
            {
                o[++nq]=y; num[nq]=y; fa[nq]=x; v[nq]=v[x]+o[x]-y;
              ls[nq]=ls[x]; o[x]-=y;
              ls[x]=nq; t[nq]=t[x];
            }
            if (ls[nq]) fa[ls[nq]]=nq;
            num[nq]+=num[ls[nq]];
            return nq;
        }
        IL int search(int y)
        {
            splay(1,0);
            int x=1;
            while (1)
            {
                down(x);
                if (num[ls[x]]+o[x]>=y&&num[ls[x]]<y)
                {
                   if (num[ls[x]]+o[x]==y) return(x);
                   return sc(x,y-num[ls[x]]);
                }
                if (num[ls[x]]+o[x]>y) x=ls[x];
                else y-=num[ls[x]]+o[x],x=rs[x];
            }
        }
        IL int split(int x,int y)
        {
            int k1=search(x),k2=search(y+2);
            splay(k1,0); 
            splay(k2,k1);
            if (o[k2]!=1)
              sc(k2,o[k2]-1);
            return ls[k2];
        }
        IL void reverse(int x,int y)
        {
            int k=split(x,y);
            rev[k]^=1; swap(ls[k],rs[k]); t[k]^=1;
        }
        IL void change(int x,int y)
        {
            int k=split(x,y);;
            int now=fa[k];
            ls[now]=0; fa[k]=0; splay(now,0); 
            now=search(2);
            splay(now,0); down(now); down(1);
            rs[1]=k; fa[k]=1; splay(k,0);
        }
        void dfs2(int x)
        {
            down(x);
            if (ls[x]) dfs2(ls[x]);
        //    a[++cnt]=v[x];
            c[++cnt]=(re){v[x],o[x],t[x],cnt3+1};
            cnt3+=o[x];
            if (rs[x]) dfs2(rs[x]);
        }
    }S;
    bool cmp(re x,re y)
    {
        return x.a<y.a;
    }
    IL int pos(int x)
    {
        if (x>tmp) return(0);
        int h=1,t=S.cnt-2;
        while (h<t)
        {
            if (f[mid].a+f[mid].b-1>=x) t=mid;
            else h=mid+1;
        }
        if (f[h].kk) return f[h].d+x-f[h].a;
        else return f[h].d+f[h].b-1-(x-f[h].a);
    }
    IL int pos2(int x)
    {
        if (c[x].kk) return c[x].a;
        else return c[x].a+c[x].b-1;
    }
    IL int fsp(ll x,int y)
    {
        ll ans=1;
        while (y)
        {
            if (y&1) ans=ans*x%mo;
            x=x*x%mo; y>>=1;
        }
        return ans;
    }
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        int n,m;
        read(n); read(m);
        tmp=n;
        int cnt=0;
        nq=3;
        S.rs[1]=2; S.rs[2]=3; S.fa[2]=1; S.fa[3]=2; S.t[2]=1;
        S.o[1]=1; S.v[1]=0; S.o[2]=n; S.v[2]=1; S.o[3]=1; S.v[3]=n+1;
        S.splay(3,0);
        rep(i,1,m)
        {
            int kk,x,y;
            read(kk); read(x); read(y);
            if (kk==0) S.change(x,y);
            else S.reverse(x,y);
        }
        S.splay(1,0);
        S.dfs2(1);
        int l=S.cnt;
        rep(i,1,l-2) f[i]=c[i+1];
        sort(f+1,f+l-2+1,cmp);
        cnt=0;
        rep(i,2,l-1)
        {
          if (c[i].b>=3) cnt+=c[i].b-2;
          if (c[i].kk)
          {
              if (c[i].b>=1&&i!=(l-1))
              {
                int k1=c[i].a+c[i].b-1,k2=pos2(i+1);
                if (pos(k1+1)<pos(k2+1)) cnt++;
            }
            if (c[i].b>=2)
            {
              int k1=c[i].a+c[i].b-2,k2=c[i].a+c[i].b-1;
              if (pos(k1+1)<pos(k2+1)) cnt++;
            }
          } else
          {
              if (c[i].b>=1&&i!=(l-1))
              {
                  int k1=c[i].a,k2=pos2(i+1);
                  if (pos(k1+1)<pos(k2+1)) cnt++;
            }
              if (c[i].b>=2)
              {
                  int k1=c[i].a+c[i].b-1,k2=c[i].a+c[i].b-2;
                  if (pos(k1+1)<pos(k2+1)) cnt++;
              }
          }
        }
        cout<<fsp(2,cnt)<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    BigDecimal工具类处理精度计算
    Redis的简单使用和介绍
    数据库优化知识总结
    js弹出QQ对话框在线交谈
    火焰灯menu修改之后,可以实现数遍点击小方块停留在当前页面
    js作用域的一个小例子
    js中this的四种调用模式
    jquery火焰等效果导航菜单
    appserver配置虚拟主机
    一个类似百度文库选中弹出个小框的效果
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/10176654.html
Copyright © 2011-2022 走看看