zoukankan      html  css  js  c++  java
  • luogu P6623 [省选联考 2020 A 卷] 树

    考试前几天刚刚考了01trie整体加一这个trick,但是我当时口胡没写。考场上乱写写了一年没写对。。。

    这个题的做法就是对每个点维护一个01trie,然后每次向上合并就啥也没有了。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int N=580000;
    int rt[N],n,p[N],head[N],cnt,pool;
    long long ans;
    struct Trie
    {
    	#define MaxN 20
    	int w[N*MaxN],ch[N*MaxN][2],xorv[N*MaxN],Cnt;
    	
    	void push_up(int k)
    	{
    		w[k]=xorv[k]=0;
    		if(ch[k][0])
    			w[k]^=w[ch[k][0]],
    			xorv[k]^=xorv[ch[k][0]]<<1;
    		if(ch[k][1])
    			w[k]^=w[ch[k][1]],
    			xorv[k]^=(xorv[ch[k][1]]<<1)|w[ch[k][1]];
    	}
    	
    	int New() {return ++pool; }
    	
    	void Insert(int &k,int x,int dep)
    	{
    		if(!k) k=New();
    		if(dep>MaxN) { w[k]^=1;return; }
    		Insert(ch[k][x&1],x>>1,dep+1);
    		push_up(k);
    	}
    	
    	void addall(int k)
    	{
    		swap(ch[k][0],ch[k][1]);
    		if(ch[k][0]) addall(ch[k][0]);
    		push_up(k);
    	}
    	
    	int merge(int a,int b)
    	{
    		if(!a||!b) return a+b;
    		w[a]^=w[b],xorv[a]^=xorv[b];
    		ch[a][0]=merge(ch[a][0],ch[b][0]);
    		ch[a][1]=merge(ch[a][1],ch[b][1]);
    		return a;
    	}
    }T;
    struct Edge
    {
    	int nxt,to;
    }g[N*2];
    
    int read()
    {
    	int x=0;
    	char c=getchar();
    	while(c<'0'||c>'9')
    		c=getchar();
    	while(c>='0'&&c<='9')
    		x=x*10+c-'0',c=getchar();
    	return x;
    }
    
    void add(int from,int to)
    {
    	g[++cnt].nxt=head[from];
    	g[cnt].to=to;
    	head[from]=cnt;
    }
    
    void init()
    {
    	n=read();
    	for (int i=1;i<=n;i++)
    		p[i]=read();
    	for (int x,i=2;i<=n;i++)
    		x=read(),
    		add(x,i),add(i,x);
    }
    
    void dfs(int x,int fa)
    {
    	T.Insert(rt[x],p[x],0);
    	for (int i=head[x];i;i=g[i].nxt)
    	{
    		int v=g[i].to;
    		if(v==fa)
    			continue;
    		dfs(v,x);
    		T.addall(rt[v]);
    		T.merge(rt[x],rt[v]);
    	}
    	ans+=T.xorv[rt[x]];
    }
    
    void work()
    {
    	dfs(1,-1);
    	printf("%lld
    ",ans);
    }
    
    signed main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    自定义tabbar
    数据存储: sqlite,coredata plist 归档
    分享(微信,微博,人人)
    OAuth协议与第三方登录:(QQ,百度,微信,微博)
    修改后台来测试APP的方法
    mysql 数据库优化之路
    tcp协议在定位中的应用(2)
    tcp协议在定位中的应用
    计算机术语中一些歧义
    网络常见问题背后的原因
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13301841.html
Copyright © 2011-2022 走看看