bzoj3166: [Heoi2013]Alo 可持久化字典树

左右两边的比i大的最近的两个值。然后可持久化字典树即可。

#include<bits/stdc++.h>
using namespace std;
int maxn=0,n,root[1600000],a[50010],cnt=0,l[1600000],r[1600000],p1[50010][25],p2[50010][25],sum[1600000],ans=0,pans=0,l1[50010],r1[50010],l2[50010],r2[50010];
void add(int &rt,int pre,int val,int id)
{
    if(!rt)rt=++cnt;
    sum[rt]=sum[pre]+1;
    if(id<0)return;
    if(val&(1<<id))
    {
        l[rt]=l[pre];
        add(r[rt],r[pre],val,id-1);
    }
    else
    {
        r[rt]=r[pre];
        add(l[rt],l[pre],val,id-1);
    }
}
void work(int L,int R,int val,int id)
{
    if(id<0)return;
    if((1<<id)&val)
    {
        if(sum[l[R]]-sum[l[L]])
        {
            pans|=(1<<id);
            work(l[L],l[R],val,id-1);
        }
        else work(r[L],r[R],val,id-1);
         
    }
    else
    {
        if(sum[r[R]]-sum[r[L]])
        {
            pans|=(1<<id);
            work(r[L],r[R],val,id-1);
        }
        else work(l[L],l[R],val,id-1);
    }
}
int main()
{
    //freopen("xf.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        maxn=max(maxn,a[i]);
        p1[i][0]=a[i];
        p2[i][0]=a[i];
        add(root[i],root[i-1],a[i],29);
    }
    int gl=log2(n)+2;
    for(int i=1;i<=gl;i++)
    {
        for(int j=1;j<=n;j++)
        {
            p1[j][i]=max(p1[j][i-1],p1[max(1,j-(1<<(i-1)))][i-1]);
            p2[j][i]=max(p2[j][i-1],p2[min(n,j+(1<<(i-1)))][i-1]);
        }
    }
    for(int i=1;i<=n;i++)
    {
        int w=i-1;
        if(i!=1&&p1[w][gl]>a[i])
        {
            for(int j=gl;j>=0;j--)
            {
                if(p1[w][j]<=a[i])
                {
                    w-=(1<<j);
                }
            }
            l1[i]=w;
            if(w!=1&&p1[w-1][gl]>a[i])
            {
                w=w-1;
                for(int j=gl;j>=0;j--)
                {
                    if(p1[w][j]<=a[i])
                    {
                        w-=(1<<j);
                    }
                }
                l2[i]=w;
                 
            }
        }
        w=i+1;
        if(i!=n&&p2[w][gl]>a[i])
        {
            for(int j=gl;j>=0;j--)
            {
                if(p2[w][j]<=a[i])
                {
                    w+=(1<<j);
                }
            }
            r1[i]=min(w,n);
            if(w!=n&&p2[w+1][gl]>a[i])
            {
                w=w+1;
                for(int j=gl;j>=0;j--)
                {
                    if(p2[w][j]<=a[i])
                    {
                        w+=(1<<j);
                        if(w>n)break;
                    }
                }
                r2[i]=min(n,w);
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]==maxn)continue;
        pans=0;
        if(l1[i])
        {
            int ll=0,rr=n;
            if(r1[i])rr=r1[i]-1;
            if(l2[i])ll=l2[i];
            work(root[ll],root[rr],a[i],29);
        }
        ans=max(ans,pans);
        pans=0;
        if(r1[i])
        {
            int ll=0,rr=n;
            if(r2[i])rr=r2[i]-1;
            if(l1[i])ll=l1[i];
            work(root[ll],root[rr],a[i],29);
        }
        ans=max(ans,pans);
    }
    printf("%d
",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/mybing/p/8810378.html