zoukankan      html  css  js  c++  java
  • [被踩计划] 题解 [省选联考 2020 A 卷] 树

    [被踩计划] 题解 [省选联考 2020 A 卷] 树

    为什么叫被踩记录呢?因为感觉自己之前真的是太菜了,打算把之前联赛等考过的题目做一做,看看自已以前有多菜,所以取名叫被踩记录。

    题目链接

    题目分析

    列个表先:

    0000
    0001
    0010
    0011
    0100
    0101
    0110
    0111
    1000
    1001
    1010
    1011
    1100
    1101
    1110
    1111
    

    不难发现,对于二进制下的第 (i) 位,如果每次加一,每隔 (2^i-1) 位这一位就会改变(由 (0)(1) 或由 (1)(0) ),我们可以考虑建 (log_2 n) 棵森林,其中第 (i(iin [0,log_2 n-1])) 棵森林中点 (x) 的父亲是原来点 (x)(2^i) 级祖先,相当于是对于每一位分开考虑,那么此时该位会发生修改的其实就是这一位对应的那棵森林中 (x) 的所有祖先,这就是很基础的树上差分了,时间复杂度 (mathcal O(nlog_2n))

    怎么说呢,果然自己当时还是太菜了。

    参考代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ch() getchar()
    #define pc(x) putchar(x)
    using namespace std;
    template<typename T>void read(T&x){
    	static char c;static int f;
    	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
    	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
    }
    template<typename T>void write(T x){
    	static char q[65];int cnt=0;
    	if(x<0)pc('-'),x=-x;
    	q[++cnt]=x%10,x/=10;
    	while(x)
    		q[++cnt]=x%10,x/=10;
    	while(cnt)pc(q[cnt--]+'0');
    }
    const int maxn=550005;
    int val[maxn],son[maxn],bro[maxn];
    void qwq(int u,int v){
    	bro[v]=son[u],son[u]=v;
    }
    int pa[maxn][21],f[maxn][21],lav[maxn];
    long long ans;
    void dfs(int u,int dp=0){
    	for(int i=1;(1<<i)<=dp;++i)
    		pa[u][i]=pa[pa[u][i-1]][i-1];
    	lav[u]=val[u];
    	for(int v=son[u];v;v=bro[v]){
    		pa[v][0]=u;dfs(v,dp+1);lav[u]^=lav[v];
    	}
    	for(int i=0;i<21;++i)if(f[u][i]){
    		lav[u]^=1<<i;f[pa[u][i]][i]^=1;
    	}
    	int no=pa[u][0];f[no][0]^=1;
    	for(int i=0;i<20;++i){
    		int o=(val[u]&1)^1;val[u]>>=1;
    		if(o)no=pa[no][i];f[no][i+1]^=1;
    	}
    	ans+=lav[u];
    }
    int main(){
    	int n;read(n);
    	for(int i=1;i<=n;++i)read(val[i]);
    	for(int i=2;i<=n;++i){
    		int p;read(p);qwq(p,i);
    	}
    	dfs(1);write(ans),pc('
    ');
    	return 0;
    }
    
    
  • 相关阅读:
    Android学习—Shape
    Android学习—Application的作用
    用户管理
    DPKG命令与软件安装、APT
    Linux学习笔记
    C如何使用内存
    九九乘法表.py
    超市买苹果.py
    第一个程序python.py
    JavaScript一些备忘知识
  • 原文地址:https://www.cnblogs.com/lsq147/p/14186085.html
Copyright © 2011-2022 走看看