[BZOJ4568][SCOI2016]幸运数字
sol
这不是线性基思博题吗
我写的是树链剖分+st表,复杂度是\(O(n\log^3n+Q\log^3n)\)的,理论上过不了。
所以需要卡一下常。比如说线性基的\(\rm merge\)里面的那个if
for (int j=63;j>=0;--j) if (b.p[j]) a.insert(b.p[j]);
code
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
ll gi()
{
ll x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 2e4+5;
struct xxj{
ll p[70];
void init(){for (int j=0;j<=63;++j) p[j]=0;}
void insert(ll x)
{
for (int j=63;j>=0;--j)
{
if (!(x>>j)) continue;
if (!p[j]) {p[j]=x;return;}
x^=p[j];
}
}
ll query(ll x)
{
for (int j=63;j>=0;--j)
x=max(x,x^p[j]);
return x;
}
}st[15][N];
xxj merge(xxj a,xxj b)
{
for (int j=63;j>=0;--j) if (b.p[j]) a.insert(b.p[j]);
return a;
}
int to[N<<1],nxt[N<<1],head[N],cnt;ll a[N];
int n,m,lg[N],fa[N],dep[N],sz[N],son[N],top[N],dfn[N],ref[N];
void link(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;}
void dfs1(int u,int f)
{
fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
for (int e=head[u];e;e=nxt[e])
{
int v=to[e];if (v==f) continue;
dfs1(v,u);
sz[u]+=sz[v];if (sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int up)
{
top[u]=up;dfn[u]=++cnt;ref[cnt]=u;
if (son[u]) dfs2(son[u],up);
for (int e=head[u];e;e=nxt[e])
if (to[e]!=fa[u]&&to[e]!=son[u])
dfs2(to[e],to[e]);
}
xxj interval(int l,int r)
{
int k=lg[r-l+1];
return merge(st[k][l],st[k][r-(1<<k)+1]);
}
xxj ask(int u,int v)
{
xxj res;res.init();
while (top[u]^top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
res=merge(res,interval(dfn[top[u]],dfn[u]));
u=fa[top[u]];
}
if (dep[u]>dep[v]) swap(u,v);
res=merge(res,interval(dfn[u],dfn[v]));
return res;
}
int main()
{
n=gi();m=gi();lg[0]=-1;
for (int i=1;i<=n;++i) lg[i]=lg[i>>1]+1,a[i]=gi();
for (int i=1;i<n;++i)
{
int u=gi(),v=gi();
link(u,v);link(v,u);
}
dfs1(1,0);cnt=0;dfs2(1,1);
for (int i=1;i<=n;++i) st[0][dfn[i]].insert(a[i]);
for (int j=1;j<15;++j)
for (int i=1;i+(1<<j-1)<=n;++i)
st[j][i]=merge(st[j-1][i],st[j-1][i+(1<<j-1)]);
while (m--)
{
int u=gi(),v=gi();
printf("%lld\n",ask(u,v).query(0));
}
return 0;
}