• P4098 [HEOI2013]ALO


    题目

    P4098 [HEOI2013]ALO

    为了个水题,调了快两个小时(emmm)

    做法

    暴力当然也能过,好像还不太好卡,数两两不同,所以两两限制通过特判的时间复杂度应该也是很优秀的,可惜(juruo)不会算,希望有(dalao)能求出大概的复杂度

    操作的区间为[左边第二大+1,右边第二大-1]

    本来想单调栈处理[左边第一大+1,右边第二大-1],但这样[左边第二大+1,左边第一大]这样的区间就没算

    然后又想(nL[i]=L[L[i]]+1,nR[i]=R[R[i]]-1),又错了,这样({4,5,7,1})其中(1)的左区间会到达第一个数

    正解:(a)从小到达排,每次把最小的数的位置在双向链表删掉,然后向左右边找当然,你也可以去肛主席树或平衡树

    My complete code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<string>
    #include<iostream>
    #include<stack>
    using namespace std;
    typedef long long LL;
    const LL maxn=3000000;
    inline LL Read(){
    	LL x(0),f(1);char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    	return x*f;
    }
    stack<LL>sta;
    LL n,ans,M;
    LL a[maxn],L[maxn],R[maxn],pre[maxn],nxt[maxn];
    struct Trie{
    	LL nod;
    	LL len,val[maxn],son[maxn][2],d[40],root[maxn];
    	inline void Build(LL &now,LL pre){
            val[now=++nod]=val[pre]+1;
            LL tmp(now);
            for(LL i=32;i>=1;--i){
                son[tmp][d[i]^1]=son[pre][d[i]^1];
                son[tmp][d[i]]=++nod;
                tmp=son[tmp][d[i]],pre=son[pre][d[i]];
                val[tmp]=val[pre]+1;
            }
        }
        inline void First(LL val){
            LL len(0);
            while(val){
                d[++len]=val&1;
                val>>=1;
            }
            for(LL i=len+1;i<=32;++i) d[i]=0;
        }
        inline void Insert(LL now,LL pre,LL val){
            First(val);
            Build(root[now],root[pre]);
        }
        inline LL Query(LL pre,LL now){
            LL ans(0);
            for(LL i=32;i>=1;--i){
                if(val[son[now][d[i]^1]]-val[son[pre][d[i]^1]]>0){
                    ans|=(1<<(i-1));
                    now=son[now][d[i]^1],pre=son[pre][d[i]^1];
                }else{
                    now=son[now][d[i]],pre=son[pre][d[i]];
                }
            }return ans;
        }
        inline LL Solve(LL pre,LL now,LL val){
            First(val);
            return Query(root[pre-1],root[now]);
        }
    }T;
    struct node{
    	LL val,id;
    	bool operator <(const node &x)const{
    		return val<x.val;
    	}
    }p[maxn];
    int main(){
    	n=Read();
    	for(LL i=1;i<=n;++i){
    	    a[i]=Read();
    	    T.Insert(i,i-1,a[i]);
    	    p[i]=(node){a[i],i};
    		pre[i]=i-1;nxt[i]=i+1;
    	}
    	pre[0]=1; nxt[n]=n;
    	sort(p+1,p+1+n);
    	for(LL i=1;i<=n;++i){
    		LL now(p[i].id);
    		nxt[pre[now]]=nxt[now],pre[nxt[now]]=pre[now];
    		L[now]=pre[pre[now]],R[now]=nxt[nxt[now]];
    	}
    	for(LL i=1;i<=n;++i)
    			ans=max(ans,T.Solve(L[i]+1,R[i]-1,a[i]));
    	printf("%lld",ans);
    	return 0;
    }/*
    */
    
  • 相关阅读:
    java 多线程小记
    Java通过反射实现实例化
    selenium webdriver 屏幕滚动
    selenium webdriver 实现百度贴吧自动签到
    selenium webdriver 小计
    JaveWeb 公司项目(7)----- 通过JS动态生成DIV
    两个DIV并排显示
    Intellij idea注册码失效
    JaveWeb 公司项目(6)----- 通过ToolTip给控件添加动态注释
    Intellij idea 添加浏览器
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10321749.html
Copyright © 2020-2023  润新知