您的位置:首页 > 其它

bzoj4568

2016-07-23 22:14 218 查看
这道题其实思维复杂度并不是很高,但是给我这种只会写树剖的人。。。那真是 要写死。。。其实方法也没什么,就是把线性基的合并过程弄到线段树上来做。这里我当时还出了些小偏差,调试的时候发现一组线性基是2 11我以为这样不算线性基,后来想起这只不过不是最简线性基罢了。。。

不过有一点值得一说。就是这个数据结构题竟然一遍ac了。。。

#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#include <set>
#include <queue>
#include <vector>
#include<map>

#define pb push_back
#define lb lower_bound
#define sqr(x) (x)*(x)
#define lowbit(x) (x)&(-x)
#define Abs(x) ((x) > 0 ? (x) : (-(x)))
#define forup(i,a,b) for(int i=(a);i<=(b);i++)
#define fordown(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1]

#define maxn 20005
#define maxm 100005
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

template<class T> inline
void read(T& num){
num = 0; bool f = true;char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}
while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}
num = f ? num: -num;
}
int out[100];
template<class T> inline
void write(T x,char ch){
if (x==0) {putchar('0'); putchar(ch); return;}
if (x<0) {putchar('-'); x=-x;}
int num=0;
while (x){ out[num++]=(x%10); x=x/10;}
fordown(i,num-1,0) putchar(out[i]+'0'); putchar(ch);
}
/*==================split line==================*/
int N,Q,cnt;
ll a[maxn];
vector<int> g[maxn];
int siz[maxn],sonh[maxn],top[maxn],ord[maxn],depth[maxn],fa[maxn];

ll b[maxn*4][65];
ll q[maxn];
int L,R;
void insert(ll *a,ll x)
{
for (int i=60;i>=0;i--)
if (x>>i&1ll)
{
if (!a[i]) {a[i]=x;break;}
else x^=a[i];
}
}
void merge(ll *a,ll *b,ll *c)
{ ll d[65];
fordown(i,60,0) d[i]=b[i];
fordown(i,60,0) if (c[i]) insert(d,c[i]);
fordown(i,60,0) a[i]=d[i];
}

void query(ll *a,int node,int tl,int tr)
{ if(tl>=L&&tr<=R)
{ merge(a,a,b[node]);
return;
}
int mid=(tl+tr)>>1;
if(mid>=L) query(a,node<<1,tl,mid);
if(mid+1<=R) query(a,node<<1|1,mid+1,tr);
}

void build(int node,int l,int r)
{ if(l==r)
{insert(b[node],q[l]);
return;
}
int mid=(l+r)>>1;
build(node<<1,l,mid);build(node<<1|1,mid+1,r);
merge(b[node],b[node],b[node<<1]);
merge(b[node],b[node],b[node<<1|1]);
}
/*===========================================*/
int dfs(int x,int f)
{ int t=0,cmax=0;
for(int i=0;i<g[x].size();i++)
{ int v=g[x][i];
if(v!=f)
{depth[v]=depth[x]+1;
fa[v]=x;
siz[v]=dfs(v,x);
siz[x]+=siz[v];
if(siz[v]>cmax)
{cmax=siz[v];
t=v;
}
}
}
sonh[x]=t;
return siz[x]+1;
}
void mark(int x,int topic)
{ cnt++; ord[x]=cnt; top[x]=topic;q[cnt]=a[x];
if(sonh[x]!=0)
{mark(sonh[x],topic);
}
for(int i=0;i<g[x].size();i++)
{ int v=g[x][i];
if(v!=sonh[x]&&v!=fa[x])
{ mark(v,v);
}
}
}

void LCA(int x,int y)
{ll a[65]={0};
if(x==y) { write(q[ord[x]],'\n');return;}
while(top[x]!=top[y])
{ if(depth[top[x]]<depth[top[y]])
swap(x,y);

L=min(ord[x],ord[top[x]]),R=max(ord[x],ord[top[x]]);
query(a,1,1,N);
x=top[x];
x=fa[x];
}

L=min(ord[x],ord[y]);R=max(ord[x],ord[y]);
query(a,1,1,N);

ll ans=0ll;
fordown(i,60,0)
ans=max(ans,ans^a[i]);
write(ans,'\n');

}

/*=============================================*/
int main()
{ read(N);read(Q);
forup(i,1,N) read(a[i]);
for(int i=1;i<N;i++)
{int x,y;read(x);read(y);
g[x].pb(y);g[y].pb(x);
}
siz[1]=dfs(1,0);
mark(1,1);
build(1,1,N);
forup(i,1,Q)
{int x,y;read(x);read(y);
LCA(x,y);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: