[HEOI2013]ALO 【可持久化Trie】

本文介绍了一种解决HEOI2013 ALO问题的有效算法。通过枚举能量次大的宝石并利用链表维护比当前宝石能量大的宝石位置,实现了快速查找。文章详细展示了具体的代码实现过程,包括插入、查询等关键操作。

[HEOI2013]ALO
从小到大枚举能量次大的宝石\(i\),令在它之前的第一个能量大于它的宝石在\(l_1\),第二个在\(l_2\),同理设\(r_1,r_2\)
\([l_2+1, r_1-1]\)\([l_1+1, r_2-1]\)包含了所有可能使\(i\)作为能量次大宝石的区间
\(l_1, l_2, r_1, r_2\)用链表,从小到大枚举\(i\),计算过\(i\)后把它从链表中去掉,剩下的一定都是比\(i+1\)能量大的宝石(不包括\(i+1\)

void ins(int i, int o, int p, int v, int now){
    if(now < 0) {val[o]=i; return ;}
    int k=v>>now&1; if(p) ch[o][k^1]=ch[p][k^1];
    ch[o][k]=++cnt; ins(i, ch[o][k], ch[p][k], v, now-1);
    val[o]=max(val[ch[o][0]], val[ch[o][1]]);
}
int query(int L, int o, int now, int x){
    if(now < 0) return a[val[o]]^x;
    int k=x>>now&1; 
    if(val[ch[o][k^1]] >= L) return query(L, ch[o][k^1], now-1, x);
    return query(L, ch[o][k], now-1, x);
}
bool cmp(int x, int y){return a[x] < a[y];}
void solve(){
    n=read(); 
    for(int i=1; i <= n; i++) a[i]=read(), 
        pk[i]=i, pre[i]=i-1, nxt[i]=i+1, 
        rt[i]=++cnt, ins(i, rt[i], rt[i-1], a[i], 30);
    sort(pk+1, pk+1+n, cmp); int res=0;
    for(int i=1; i < n; i++){
        int x=pk[i], l=pre[x], r=nxt[x], ans=0; nxt[l]=nxt[x], pre[r]=pre[x];
        if(l) ans=max(ans, query(pre[l]+1, rt[r-1], 30, a[x]));
        if(r <= n) ans=max(ans, query(l+1, rt[nxt[r]-1], 30, a[x]));
        res=max(res, ans);
    }
    printf("%d", res);
}

转载于:https://www.cnblogs.com/zerolt/p/9295487.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值