zoukankan      html  css  js  c++  java
  • P6086 【模板】Prufer 序列

    题意

    (prufer)序列和树的互相转化。

    分析

    模板题,要背一遍。

    一些性质:

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    #define ll long long
    const int N=5e6+5;
    int n,m;
    int fa[N],pru[N],d[N];
    ll Ans;
    void TreetoPrufer(){
    	for(int i=1;i<=n-1;i++) d[fa[i]]++;
    	for(int i=1,now=1;i<=n-1;i++,now++){
    		while(d[now]) now++;
    		pru[i]=fa[now];
    		while(i<n-2&&!--d[pru[i]]&&pru[i]<now) pru[i+1]=fa[pru[i]],i++;
    	}
    	return;
    } 
    void PrufertoTree(){
    	for(int i=1;i<=n-2;i++) d[pru[i]]++;
    	pru[n-1]=n;
    	for(int i=1,now=1;i<=n-1;i++,now++){
    		while(d[now]) now++;
    		fa[now]=pru[i];
    		while(i<n-1&&!--d[pru[i]]&&pru[i]<now) fa[pru[i]]=pru[i+1],i++;
    	}
    	
    	return ;
    }
    signed main(){
    	read(n),read(m);
    	if(m==1){
    		for(int i=1;i<=n-1;i++) read(fa[i]);
    		TreetoPrufer();
    		for(int i=1;i<=n-2;i++) Ans^=1ll*i*pru[i];
    	}
    	else{
    		for(int i=1;i<=n-2;i++) read(pru[i]);
    		PrufertoTree();
    		for(int i=1;i<=n-1;i++) Ans^=1ll*i*fa[i];
    	}
    	write(Ans);
    	return 0;
    }
    
  • 相关阅读:
    修理牛棚 贪心 USACO
    零件加工 贪心 题解
    花店橱窗 动态规划 题解
    动态规划 摆花 题解
    NOIP2004普及组第3题 FBI树
    实况世界杯4小游戏链接
    poj2761(treap入门)
    最大连续子序列和(分治法)
    任意区间的最长连续递增子序列,最大连续子序列和
    lca转RMQ
  • 原文地址:https://www.cnblogs.com/Akmaey/p/15032083.html
Copyright © 2011-2022 走看看