zoukankan      html  css  js  c++  java
  • [BZOJ5361][Lydsy1805月赛]对称数

    bzoj

    Description

    给你一棵树,每个点有一个编号(a_i)(Q)组询问,每次问一条路径上最小的出现了偶数次的编号是多少(包括零次)。
    多组数据,(Tle10,n,Q,a_ile200000)

    sol

    这又是一道随机化神题。
    给每个编号随机一个(unsigned long long)范围内的权值(val_i)
    对于一次询问,统计路径上所有编号(in [l,mid])的点的权值的异或和。如果这个异或和不等于(val_lotimes val_{l+1}otimes...otimes val_{mid}),就说明这个([l,mid])内至少有一个编号出现了偶数次,否则说明所有编号都出现了奇数次。建立主席树后在主席树上二分即可。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<ctime>
    using namespace std;
    int gi(){
    	int 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;
    }
    #define ull unsigned long long
    const int N = 2e5+5;
    struct president_tree{int ls,rs;ull sum;}t[N*25];
    int n,m,to[N<<1],nxt[N<<1],head[N],cnt,col[N],mx;
    int fa[N],dep[N],sz[N],son[N],top[N],rt[N],tot;
    ull val[N],sum[N];
    void link(int u,int v){
    	to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
    }
    void modify(int &x,int l,int r,int p){
    	t[++tot]=t[x];t[x=tot].sum^=val[p];
    	if (l==r) return;int mid=l+r>>1;
    	if (p<=mid) modify(t[x].ls,l,mid,p);
    	else modify(t[x].rs,mid+1,r,p);
    }
    int query(int x,int y,int z,int w,int l,int r){
    	if (l==r) return l;int mid=l+r>>1;
    	if ((t[t[x].ls].sum^t[t[y].ls].sum^t[t[z].ls].sum^t[t[w].ls].sum)!=(sum[mid]^sum[l-1]))
    		return query(t[x].ls,t[y].ls,t[z].ls,t[w].ls,l,mid);
    	else return query(t[x].rs,t[y].rs,t[z].rs,t[w].rs,mid+1,r);
    }
    void dfs1(int u,int f){
    	fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
    	modify(rt[u]=rt[f],1,mx,col[u]);
    	for (int e=head[u];e;e=nxt[e])
    		if (to[e]!=f){
    			dfs1(to[e],u),sz[u]+=sz[to[e]];
    			if (sz[to[e]]>sz[son[u]]) son[u]=to[e];
    		}
    }
    void dfs2(int u,int up){
    	top[u]=up;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]);
    }
    int lca(int u,int v){
    	while (top[u]^top[v]){
    		if (dep[top[u]]<dep[top[v]]) swap(u,v);
    		u=fa[top[u]];
    	}
    	return dep[u]<dep[v]?u:v;
    }
    int main(){
    	srand(20020415);
    	for (int i=1;i<=200001;++i) val[i]=(ull)rand()*rand()*rand(),sum[i]=sum[i-1]^val[i];
    	int T=gi();while (T--){
    		n=gi();m=gi();mx=0;
    		memset(head,0,sizeof(head));cnt=0;
    		memset(t,0,sizeof(t));tot=0;
    		memset(son,0,sizeof(son));
    		memset(rt,0,sizeof(rt));
    		for (int i=1;i<=n;++i) col[i]=gi(),mx=max(mx,col[i]);++mx;
    		for (int i=1;i<n;++i){
    			int u=gi(),v=gi();
    			link(u,v),link(v,u);
    		}
    		dfs1(1,0),dfs2(1,1);
    		while (m--){
    			int u=gi(),v=gi(),gg=lca(u,v);
    			printf("%d
    ",query(rt[u],rt[v],rt[gg],rt[fa[gg]],1,mx));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    日期型数据知识
    如何让VS检查函数和类Comment的添加情况
    HTTP request is unauthorized with client authentication scheme 'Anonymous'.
    将SerializableAttribute序列化为xml
    使用EnterpriseLibrary Validation Block对WCF做验证
    表达式树中递归方法
    使用SignalR在Asp.net中实现进度条
    SQLServer中列出数据库的所有表的创建时间
    用Knockoutjs与Asp.net MVC实现级联下拉列表
    使用UnityAutoMoq简化单元测试
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9115984.html
Copyright © 2011-2022 走看看