zoukankan      html  css  js  c++  java
  • BZOJ 3166 Alo

    处理出每个数最靠近它的左右两个比它大的数。

    然后可持久化trie。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 200050
    #define inf 1000000007
    using namespace std;
    struct num
    {
        int val,id;
    }p[maxn];
    int n,a[maxn];
    int seg_ls[maxn<<2],seg_rs[maxn<<2],val1[maxn<<2],val2[maxn<<2],seg_root,seg_tot=0,l1[maxn],l2[maxn],r1[maxn],r2[maxn];
    int tree[maxn*50][2],sum[maxn*50],root[maxn],bitt[35],ans=0,tot=0;
    bool cmp(num x,num y)
    {
        return x.val>y.val;
    }
    void get_table()
    {
        bitt[0]=1;
        for (int i=1;i<=30;i++)
            bitt[i]=bitt[i-1]*2;
    }
    void build_seg(int &now,int left,int right)
    {
        now=++seg_tot;val1[now]=0;val2[now]=inf;
        if (left==right) return;
        int mid=(left+right)>>1;
        build_seg(seg_ls[now],left,mid);
        build_seg(seg_rs[now],mid+1,right);
    }
    int ask_seg(int now,int left,int right,int pos,int type)
    {
        if (left==right)
        {
            if (type==1) return val1[now];
            else return val2[now]; 
        }
        int mid=(left+right)>>1;
        if (type==1)
        {
            if (pos<=mid) return max(val1[now],ask_seg(seg_ls[now],left,mid,pos,type));
            else return max(val1[now],ask_seg(seg_rs[now],mid+1,right,pos,type));
        }
        else
        {
            if (pos<=mid) return min(val2[now],ask_seg(seg_ls[now],left,mid,pos,type));
            else return min(val2[now],ask_seg(seg_rs[now],mid+1,right,pos,type));
        }
    }
    void modify_seg(int now,int left,int right,int l,int r,int x,int type)
    {
        if ((left==l) && (right==r))
        {
            if (type==1) val1[now]=max(val1[now],x);
            else val2[now]=min(val2[now],x);
            return;
        }    
        int mid=(left+right)>>1;
        if (r<=mid) modify_seg(seg_ls[now],left,mid,l,r,x,type);
        else if (l>=mid+1) modify_seg(seg_rs[now],mid+1,right,l,r,x,type);
        else
        {
            modify_seg(seg_ls[now],left,mid,l,mid,x,type);
            modify_seg(seg_rs[now],mid+1,right,mid+1,r,x,type);
        }
    }
    void work(int x)
    {
        l1[p[x].id]=ask_seg(seg_root,1,n,p[x].id,1);
        if (l1[p[x].id]==0) l2[p[x].id]=0;
        else
        {
            if (l1[p[x].id]==1) l2[p[x].id]=0;
            else l2[p[x].id]=ask_seg(seg_root,1,n,l1[p[x].id]-1,1);
        }
        r1[p[x].id]=ask_seg(seg_root,1,n,p[x].id,2);
        if (r1[p[x].id]==inf) {r1[p[x].id]=n+1;r2[p[x].id]=n+1;}
        else
        {
            if (r1[p[x].id]==n) r2[p[x].id]=n+1;
            else r2[p[x].id]=ask_seg(seg_root,1,n,r1[p[x].id]+1,2);
            if (r2[p[x].id]==inf) r2[p[x].id]=n+1;
        }
        modify_seg(seg_root,1,n,p[x].id,n,p[x].id,1);
        modify_seg(seg_root,1,n,1,p[x].id,p[x].id,2);
    }
    void insert(int b,int last,int &now,int x)
    {
        now=++tot;
        tree[now][0]=tree[last][0];tree[now][1]=tree[last][1];
        sum[now]=sum[last]+1;
        if (b==-1) return;
        int tmp=x&bitt[b];tmp>>=b;
        insert(b-1,tree[last][tmp],tree[now][tmp],x);
    }
    int ask(int b,int last,int now,int x)
    {
        if (b==-1) return 0;
         int tmp=x&bitt[b];tmp>>=b;
        int r=sum[tree[now][tmp^1]]-sum[tree[last][tmp^1]];
        if (r>0) return ask(b-1,tree[last][tmp^1],tree[now][tmp^1],x)+bitt[b];
        else return ask(b-1,tree[last][tmp],tree[now][tmp],x);
    }
    int main()
    {
        get_table();
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            p[i].val=a[i];p[i].id=i;
        }
        sort(p+1,p+n+1,cmp);
        build_seg(seg_root,1,n);
        for (int i=1;i<=n;i++)
            work(i);
        for (int i=1;i<=n;i++)
            insert(30,root[i-1],root[i],a[i]);
        for (int i=1;i<=n;i++)
        {
            int l,r;
            l=l2[i]+1;r=r1[i]-1;
            ans=max(ans,ask(30,root[l-1],root[r],a[i]));
            l=l1[i]+1;r=r2[i]-1;
            ans=max(ans,ask(30,root[l-1],root[r],a[i]));
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Ansible自动部署lnmp架构+上线电商
    elastalert 基于EFK环境的邮件报警
    冒泡法、选择法、插入法排序
    Java的基本数据类型
    cmd运行java程序找不到或无法加载主类解决办法
    JavaBean进行表单开发
    Web项目各目录详解
    【数论】整数分块及详细证明
    题解 P4874 【[USACO14DEC] Piggyback_Silver 背负式运输(银)】
    题解 P3792 【由乃与大母神原型和偶像崇拜】
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5735479.html
Copyright © 2011-2022 走看看