• 一本通1762:与非


    链接

    对于不满足结合律的运算,要处理出两个方向的结果,查询时也要注意方向。

    (太菜了。。。被卡常惹。。。

    #include<bits/stdc++.h>
    #define re register
    #define IL inline
    #define LL unsigned int
    using namespace std;
    const int N=1e5+3;
    struct hh{
    	int to,nxt;
    }e[N<<1];
    int n,m,k,K,num,fir[N],dfn[N],rev[N],top[N],siz[N],son[N],dep[N],fa[N];
    LL w[N],Ans,ans[32];
    IL LL in(){
    	char c;
    	while((c=getchar())<'0'||c>'9');
    	LL x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x;
    }
    IL void add(int x,int y){e[++num]=(hh){y,fir[x]},fir[x]=num;}
    IL int nand(int x,int y){return !(x&y);}
    void dfs1(int u,int f){
    	fa[u]=f,dep[u]=dep[f]+1,siz[u]=1;
    	for(re int i=fir[u],v;v=e[i].to;i=e[i].nxt)
    	  if(v^f){
    	  	dfs1(v,u),siz[u]+=siz[v];
    	  	if(siz[son[u]]<siz[v]) son[u]=v;
    		}
    }
    void dfs2(int u,int t){
    	top[u]=t,rev[dfn[u]=++num]=u;
    	if(son[u]) dfs2(son[u],t);
    	for(re int i=fir[u],v;v=e[i].to;i=e[i].nxt)
    	  if(v^fa[u]&&v^son[u]) dfs2(v,v);
    }
    IL int get_lca(int x,int y){
    	while(top[x]^top[y]) dep[top[x]]<dep[top[y]]?y=fa[top[y]]:x=fa[top[x]];
    	return dep[x]<dep[y]?x:y;
    }
    struct segment{
    	int L[32][N<<2][2],R[32][N<<2][2];
    	IL void pushup(int k){
    		int ls=k<<1,rs=k<<1|1;
    		for(re int i=0;i<K;++i)
    		  L[i][k][0]=L[i][rs][L[i][ls][0]],
    		  L[i][k][1]=L[i][rs][L[i][ls][1]],
    		  R[i][k][0]=R[i][ls][R[i][rs][0]],
    		  R[i][k][1]=R[i][ls][R[i][rs][1]];
    	}
    	IL void gx(int k,LL w){
    		for(re int i=0;i<K;++i)
    		  L[i][k][0]=R[i][k][0]=nand(0,w>>i&1),
    		  L[i][k][1]=R[i][k][1]=nand(1,w>>i&1);
    	}
    	void build(int k,int l,int r){
    		if(l==r){gx(k,w[rev[l]]);return;}
    		int mid=l+r>>1;
    		build(k<<1,l,mid),build(k<<1|1,mid+1,r),pushup(k);
    	}
    	void mdy(int k,int l,int r,int u,LL v){
    		if(l==r){gx(k,v);return;}
    		int mid=l+r>>1;
    		if(u<=mid) mdy(k<<1,l,mid,u,v);
    		else mdy(k<<1|1,mid+1,r,u,v);
    		pushup(k);
    	}
    	void query_R(int k,int l,int r,int ll,int rr){//从下到上 
    		if(l>=ll&&r<=rr){
    			for(re int i=0;i<K;++i)
    		    ans[i]=R[i][k][ans[i]];
    		  return;
    		}
    		int mid=l+r>>1;
    		if(rr>mid) query_R(k<<1|1,mid+1,r,ll,rr);
    		if(ll<=mid) query_R(k<<1,l,mid,ll,rr);
    	}
    	void query_L(int k,int l,int r,int ll,int rr){//从上到下 
    		if(l>=ll&&r<=rr){
    			for(int i=0;i<K;++i)
    		    ans[i]=L[i][k][ans[i]];
    		  return;
    		}
    		int mid=l+r>>1;
    		if(ll<=mid) query_L(k<<1,l,mid,ll,rr);
    		if(rr>mid) query_L(k<<1|1,mid+1,r,ll,rr);
    	}
    }T;
    void dfs(int y,int lca){
    	if(top[y]==top[lca]){
    		if(y^lca) T.query_L(1,1,n,dfn[lca]+1,dfn[y]);
    		return;
    	}
    	dfs(fa[top[y]],lca);
    	T.query_L(1,1,n,dfn[top[y]],dfn[y]);
    }
    int Query(int x,int y){
    	memset(ans,Ans=0,sizeof(ans));
    	int lca=get_lca(x,y);
    	while(top[x]^top[lca]) 
    	  T.query_R(1,1,n,dfn[top[x]],dfn[x]),x=fa[top[x]];
    	T.query_R(1,1,n,dfn[lca],dfn[x]);
    	dfs(y,lca);
    	for(int i=0;i<K;++i) Ans|=ans[i]<<i;
    	return Ans;
    }
    int main()
    {
    	LL x,y,z;char s[10];
    	n=in(),m=in(),k=K=in();
    	for(re int i=1;i<=n;++i) w[i]=in();
    	for(re int i=1;i<n;++i)
    	  x=in(),y=in(),
    	  add(x,y),add(y,x);
    	num=0,dfs1(1,0),dfs2(1,1);
    	T.build(1,1,n);
    	while(m--){
    		scanf("%s",s+1),x=in(),y=in();
    		if(s[1]=='Q') printf("%u
    ",Query(x,y));
    		else T.mdy(1,1,n,dfn[x],y);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Hive的安装搭建(二)
    Hive的基本介绍(一)
    HADOOP之HDFS使用idea练习MapReduce(八)
    HADOOP之HDFS使用idea操作MapReduce(七)
    HADOOP之HDFS增加MapReduce(六)
    HADOOP之HDFS用idea操作(五)
    HADOOP之HDFS环境搭建(四)
    HADOOP之HDFS环境搭建(三)
    HADOOP之HDFS环境搭建(二)
    HADOOP之HDFS环境搭建(一)
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/13922033.html
Copyright © 2020-2023  润新知