zoukankan      html  css  js  c++  java
  • 51Nod 算法马拉松28 A题 先序遍历与后序遍历 分治

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - 51Nod1832


    题意概括

      对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的二叉树。
      两棵二叉树不同当且仅当对于某个x,x的左儿子编号不同或x的右儿子编号不同。


    题解

      我们发现,如果两棵二叉树先后序遍历相同,但是形态不同,只可能是某些节点,只有一个子节点,这个子节点在左边和右边都可以的情况。

      那么只需要统计这样的节点个数,然后2^tot,高精度即可。


    代码

    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    const int N=10000+5;
    int n,tot,a[N],b[N],pa[N],pb[N];
    int d,x[1005];
    void dfs(int la,int ra,int lb,int rb){
    	if (la==ra)
    		return;
    	la++,rb--;
    	int p=pb[a[la]];
    	if (p==rb){
    		tot++;
    		dfs(la,ra,lb,rb);
    		return;
    	}
    	int s=p-lb+1;
    	dfs(la,la+s-1,lb,lb+s-1);
    	dfs(la+s,ra,lb+s,rb);
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[i]),pa[a[i]]=i;
    	for (int i=1;i<=n;i++)
    		scanf("%d",&b[i]),pb[b[i]]=i;
    	tot=0;
    	dfs(1,n,1,n);
    	memset(x,0,sizeof x);
    	d=1,x[1]=1;
    	while (tot--){
    		int mod=1e9;
    		for (int i=1;i<=d;i++)
    			x[i]<<=1;
    		for (int i=1;i<=d;i++)
    			x[i+1]+=x[i]/mod,x[i]%=mod;
    		if (x[d+1])
    			d++;
    	}
    	printf("%d",x[d]);
    	for (int i=d-1;i>0;i--)
    		printf("%09d",x[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    tcp/ip--百度百科
    Web service--百度百科
    .NET--百度百科
    ibatis--百度百科
    Struts2--百度百科
    spring--百度百科
    从头认识Spring-1.15 对SpEl的值的操作(1)-数值运算
    performSelector 方法的自己主动俘获特性
    图解WinHex使用入门
    LINQ使用与并行
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/51Nod1832.html
Copyright © 2011-2022 走看看