2022春每日一题:Day 33
题目:[USACO 6.1.3] Cow XOR
没找到这题具体网址,这个题就是求最大异或区间(总长度尽量小,右端点尽量大)
嗯很显然一个[l,r]的异或和=s[r]s[l-1],那么现在有了优秀的n2做法
不难(很难)联想trie树,枚举1到n每次把1...i的异或和加入trie树中,然后跑一遍找最大值(史记上就是trie树维护这个n^2算法,降低了复杂度)
代码:
#include
#include
#include
#include
const int N=1e5+5;
using namespace std;
int n,m,tot,ret=-1,lr,rr,a[N],sum;
namespace trietree
{
struct trie
{
int son[2],tag;
}e[N*22];
void insert(int x,int id)
{
int p=0;
for(int i=21;i>=0;i--)
{
int k=x>>i&1;
if(!e[p].son[k])
e[p].son[k]=++tot;
p=e[p].son[k];
}
e[p].tag=id;
}
int query(int x,int &ans)
{
int p=0;
for(int i=21;i>=0;i--)
{
int k=x>>i&1;
if(!e[p].son[k^1])
p=e[p].son[k];
else
p=e[p].son[k^1],ans+=1<ret)
{
ret=ans;
rr=i,lr=l;
}
}
printf("%d %d %d\n",ret,lr+1,rr);
return 0;
}