嘘~ 正在从服务器偷取页面 . . .

Co_


Codechef REBXOR 题解

题目链接:Nikitosh and xor

题意

给定 nn 个数 ,求

max1l1r1<l2r2n{(r1i=l1ai)+(r2i=l2ai)}max1l1r1<l2r2n{(r1i=l1ai)+(r2i=l2ai)}

2n4×105, 0ai1092n4×105, 0ai109

先考虑只有 r1i=l1air1i=l1ai 该怎么求

u1s1,我觉得目前能看到我博客的人应该都会求 r1i=l1air1i=l1ai 的最大值吧

那就直接建一个 01trie01trie 把异或前缀和全插入

然后在树上贪心找较大异或值就好啦

那么两个的情况其实是一样的

其实难在选第二个可能会与第一个有交集,以及不好枚举之类的问题

考虑从左往右依次插入每个串,这样枚举第一个是不重不漏的

此时 i 右侧的都没有插,但是我们要知道 i+1n 的最大答案,然后把它们合并

怎么办?预处理呗!设 resi 表示 in 的最大值

这个预处理只要一开始从右往左跑一遍就好啦!

时间复杂度 O(nlogmax{ai})

代码:

cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdarg>
#include <cmath>
#include <iomanip>
#include <random>
using namespace std;
// #define int long long
// #define INF 0x3f3f3f3f3f3f3f3f
namespace FastIO
{
    #define gc() readchar()
    #define pc(a) putchar(a)
    #define SIZ (int)(1e6+15)
    char buf1[SIZ],*p1,*p2;
    char readchar()
    {
        if(p1==p2)p1=buf1,p2=buf1+fread(buf1,1,SIZ,stdin);
        return p1==p2?EOF:*p1++;
    }
    template<typename T>void read(T &k)
    {
        char ch=gc();T x=0,f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
        k=x*f;
    }
    template<typename T>void write(T k)
    {
        if(k<0){k=-k;pc('-');}
        static T stk[66];T top=0;
        do{stk[top++]=k%10,k/=10;}while(k);
        while(top){pc(stk[--top]+'0');}
    }
}using namespace FastIO;
#define N ((int)(4e5+15))
#define L (N << 5)

void up(int &x,int y){ x = (x > y) ? x : y;}
int n,a[N],res[N];
struct Trie
{
    int tot,trie[L][2],ed[L];
    void clear()
    {
        tot=0;
        memset(trie,0,sizeof(trie));
        memset(ed,0,sizeof(ed));
    }
    void insert(int i)
    {
        int u=0, x=a[i];
        for(int j=30,c; j>=0; j--)
        {
            c = (x >> j) & 1;
            if(!trie[u][c]) trie[u][c]=++tot;
            u=trie[u][c];
        }
        ed[u]=i;
    }
    // find max{x xor a[j]} (j ≠ i)
    int query(int x)
    {
        int u=0;
        for(int j=30,c; j>=0; j--)
        {
            c = (x >> j) & 1;
            if(trie[u][c^1]) u=trie[u][c^1];
            else if(trie[u][c]) u=trie[u][c];            
        }
        return a[ed[u]];
    }
}tr;
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    read(n);
    for(int i=1; i<=n; i++)
    {
        read(a[i]);
        a[i] ^= a[i-1];
    }
    for(int i=n-1; i; i--)
    {
        tr.insert(i+1);
        res[i] = a[i] ^ tr.query(a[i]);
        up(res[i], res[i+1]);
    }
    int ans=0; tr.clear();
    for(int i=1,cur; i<n; i++)
    {
        tr.insert(i-1);
        cur = a[i] ^ tr.query(a[i]);
        up(ans, cur + res[i]);
    }
    write(ans);
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3
  目录