zoukankan      html  css  js  c++  java
  • 【题解】hdu4757 【TJOI2018】异或

    题目链接

    题目大意:有一颗树,有点权,每次询问:一条路径(x->y)中与(z)异或的最大值,或是以(x)为根的子树中与(y)异或的最大值。

    树剖……还是算了。

    观察到,子树的(dfn)序是连续的一段区间。于是我们可以预处理(dfs)序来解决这个问题。

    第二问,我们可以求两点的最近公共祖先,做一个树上差分来实现。

    维护两颗可持久化(Trie.)一个维护(dfs)序,一个维护(x->root).

    当然(HDU)的那个题是没有第一个操作的,但是是多组询问。

    (HDU:)

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+10;
    int n,m,siz[MAXN],dfn[MAXN],f[MAXN][25];
    int dep[MAXN],head[MAXN<<1],tot,dfstime;
    int pre[MAXN],a[MAXN];
    struct edge{
    	int nxt,to;
    }e[MAXN<<1];
    inline void add(int x,int y){
    	e[++tot].to=y;
    	e[tot].nxt=head[x];
    	head[x]=tot;
    }
    struct Trie{
    	int son[MAXN<<5][2],ct[MAXN<<5],root[MAXN],cnt=1;
    	void Insert(int &rt,int x,int T){
    		ct[++cnt]=ct[rt]+1;
    		son[cnt][0]=son[rt][0];
    		son[cnt][1]=son[rt][1];
    		rt=cnt;
    		if(T==-1)return;
    		bool y=(x>>T)&1;
    		Insert(son[rt][y],x,T-1);
    	}
    	void Ins(int pre,int rt,int x){
    		root[rt]=root[pre];
    		Insert(root[rt],x,30);
    	}
    	int Q(int i,int j,int x,int T){
    		if(T==-1)return 0;
    		int y=(x>>T)&1;
    		if(ct[son[j][1^y]]>ct[son[i][1^y]])return ((1<<T)+Q(son[i][1^y],son[j][1^y],x,T-1));
    		return Q(son[i][y],son[j][y],x,T-1);
    	} 
    	int QT(int i,int j,int lc,int flc,int x,int T){
    		if(T==-1)return 0;
    		int y=(x>>T)&1;
    		if(ct[son[i][1^y]]+ct[son[j][1^y]]>ct[son[lc][1^y]]+ct[son[flc][1^y]])return ((1<<T)+QT(son[i][1^y],son[j][1^y],son[lc][1^y],son[flc][1^y],x,T-1));
    		else return QT(son[i][y],son[j][y],son[lc][y],son[flc][y],x,T-1);
    	}
    	int query(int i,int j,int x){
    		return Q(root[i-1],root[j],x,30);
    	}
    	int UQT(int i,int j,int lc,int flc,int x){
    		return QT(root[i],root[j],root[lc],root[flc],x,30);
    	}
    	void clear(){
    		cnt=1;
    		memset(root,0,sizeof(root));
    		memset(ct,0,sizeof(ct));
    		memset(son,0,sizeof(son));
    	}
    }tr1;
    void dfs(int u,int fa){
    	dep[u]=dep[fa]+1;siz[u]=1;
    	pre[dfn[u]=++dfstime]=u;
    	f[u][0]=fa;
    	for(int i=1;i<=22;++i)f[u][i]=f[f[u][i-1]][i-1];
    	tr1.Ins(fa,u,a[u]);
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v==fa)continue;
    		dfs(v,u);siz[u]+=siz[v];
    	}
    }
    int LCA(int u,int v){
    	if(dep[u]<dep[v])u^=v^=u^=v;
    	for(int i=22;i>=0;--i)
    		if(dep[f[u][i]]>=dep[v])u=f[u][i];
    	if(u==v)return u;
    	for(int i=22;i>=0;--i)
    		if(f[u][i]!=f[v][i])
    			u=f[u][i],v=f[v][i];
    	return f[u][0];
    }
    void work(){
    	int x,y,z;
    	scanf("%d%d%d",&x,&y,&z);
    	int A=LCA(x,y);
    	printf("%d
    ",tr1.UQT(x,y,A,f[A][0],z));
    }
    int main(){
    	while(~scanf("%d%d",&n,&m)){
    		for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    		for(int i=1;i<n;++i){
    			int u,v;
    			scanf("%d%d",&u,&v);
    			add(u,v);add(v,u);
    		}
    		dfs(1,0);
    		for(;m;m--)work();
    		memset(a,0,sizeof(a));
    		dfstime=0;tot=0;
    		memset(dfn,0,sizeof(dfn));
    		memset(pre,0,sizeof(pre));
    		memset(dep,0,sizeof(dep));
    		memset(siz,0,sizeof(siz));
    		memset(f,0,sizeof(f));
    		memset(head,0,sizeof(head));
    		tr1.clear();
    	} 
    	
    	return 0;
    }
    

    (Luogu:)

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=2e5+10;
    inline int read(){
    	int s=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')w=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    		s=(s<<1)+(s<<3)+(ch^48);
    		ch=getchar();
    	}
    	return w==-1?-s:s;
    }
    int n,m,dep[MAXN],a[MAXN],siz[MAXN],dfn[MAXN];
    int tot,ktot,head[MAXN<<1],pre[MAXN],f[MAXN][25];
    struct edge{
    	int nxt,to;
    }e[MAXN<<1];
    inline void add(int x,int y){
    	e[++tot].to=y;
    	e[tot].nxt=head[x];
    	head[x]=tot;
    }
    struct Trie{
    	int son[MAXN<<5][2],cnt=1,root[MAXN],ct[MAXN<<5];
    	void Insert(int &rt,int x,int T){
    		ct[++cnt]=ct[rt]+1,son[cnt][0]=son[rt][0];
    		son[cnt][1]=son[rt][1];rt=cnt;
    		if(T==-1)return;
    		bool y=(x>>T)&1;
    		Insert(son[rt][y],x,T-1);
    	}
    	inline void Ins(int pre,int rt,int x){
    		root[rt]=root[pre];
    		Insert(root[rt],x,30);
    	}
    	int Q(int i,int j,int x,int T){
    		if(T==-1)return 0;
    		bool y=(x>>T)&1;
    		if(ct[son[j][1^y]]>ct[son[i][1^y]])return ((1<<T)+Q(son[i][1^y],son[j][1^y],x,T-1));
    		return Q(son[i][y],son[j][y],x,T-1);
    	}
    	int QT(int i,int j,int lc,int flc,int x,int T){
    		if(T==-1)return 0;
    		bool y=(x>>T)&1;
    		if(ct[son[j][1^y]]+ct[son[i][1^y]]>ct[son[lc][1^y]]+ct[son[flc][1^y]])return ((1<<T)+QT(son[i][1^y],son[j][1^y],son[lc][1^y],son[flc][1^y],x,T-1));
    		else return QT(son[i][y],son[j][y],son[lc][y],son[flc][y],x,T-1);
    	}
    	int query(int l,int r,int x){return Q(root[l-1],root[r],x,30);}
    	int UQT(int i,int j,int lc,int flc,int x,int T){
    		return QT(root[i],root[j],root[lc],root[flc],x,T);
    	}
    }tr1,tr2;
    void dfs(int u,int fa){
    	dep[u]=dep[fa]+1;f[u][0]=fa;
    	dfn[u]=++ktot;pre[ktot]=u;
    	tr1.Ins(fa,u,a[u]);siz[u]=1;
    	for(int i=1;i<=22;++i)f[u][i]=f[f[u][i-1]][i-1];
    	for(int i=head[u];i;i=e[i].nxt){
    		int j=e[i].to;
    		if(j==fa)continue;
    		dfs(j,u);siz[u]+=siz[j];
    	}
    }
    int LCA(int x,int y){
    	if(dep[x]<dep[y])swap(x,y);
    	for(int i=22;i>=0;--i)
    		if(dep[f[x][i]]>=dep[y])x=f[x][i];
    	if(x==y)return x;
    	for(int i=22;i>=0;--i)
    		if(f[x][i]!=f[y][i])
    			x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1;i<n;++i){
    		int u=read(),v=read();
    		add(u,v);add(v,u);
    	}
    	dfs(1,0);
    	for(int i=1;i<=n;++i)tr2.Ins(i-1,i,a[pre[i]]);
    	for(;m;--m){
    		int opt=read();
    		if(opt==1){
    			int x=read(),y=read();
    			printf("%d
    ",tr2.query(dfn[x],dfn[x]+siz[x]-1,y));
    		}
    		else {
    			int x=read(),y=read(),z=read(),A=LCA(x,y);
    			printf("%d
    ",tr1.UQT(x,y,A,f[A][0],z,30));
    		}
    	}
    	return 0;
    } 
    
  • 相关阅读:
    setlocale
    c++的 程序实体 作用域 名空间 变量生存期概念理解
    本人的Ubuntu 10.04配置清单
    hadoopStreamming 编程 Angels
    级联 mapreduce (Cascading Mapreduce) Angels
    委托
    OPC和XML/SOAP/Web Services
    实例管理2(会话服务)
    实例管理3()
    操作(Operation)
  • 原文地址:https://www.cnblogs.com/h-lka/p/12494121.html
Copyright © 2011-2022 走看看