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;
}
不过有一点值得一说。就是这个数据结构题竟然一遍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;
}
相关文章推荐
- Android Q&A
- Sass之注释学习教程
- MQ学习之实现商品的数据同步
- 彻底解决Fragment重复加载问题,杜绝一切卡顿现象
- CentOS配置NFS server
- 排序算法及优化举例
- DP问题总结 ~
- 游戏引擎
- python matplotlib 绘图
- 页面的图片显示
- java-框架-Quartz
- 一些DP
- Spark钨丝计划:让火花(Spark)更接近灯丝(Rare Metal)详解(3)
- /storage/sdcard, /sdcard, /mnt/sdcard 三者的区别
- Dialog的重构+接口回调
- 习题19 函数和变量
- 7.15 编写一个程序,将字符数组s2中的全部字符拷贝到字符数组s1中,不用strcpy函数。拷贝时,'\0'也要拷贝过去,'\0'后面的字符不拷贝。
- 安卓自定义View进阶:Path基本操作
- Java7并发编程--1、线程管理
- StringBuffer和StringBuilder的区别