ZOJ 3602 Count the Trees

题意:

两棵树(10^5个节点)  问其中有多少对子树是同构的

思路:

树的同构一般使用hash来判断

hash函数为1、val=A   2、val = (val*P)^Soni%Q  其中Soni为第i个子树的hash值  3、val=val*B%Q

注意Son值应该排序  (本题因为左右子树是区分开的  因此不用排序)

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef unsigned long long ULL;
#define N 100010
#define A 1333333331LL
#define B 1333333333331LL
#define P 133331LL
#define Q 1333333333333331LL

int T,n,m;
int l[2][N],r[2][N];
ULL ans;
map<ULL,ULL> cnt;

ULL dfs(int u,int f){
	ULL val=A;
	if(l[f][u]!=-1){
		ULL tmp=dfs(l[f][u],f);
		val=((val*P)^tmp)%Q;
	}else{
		ULL tmp=(A&B^P);
		val=((val*P)^tmp)%Q;
	}
	if(r[f][u]!=-1){
		ULL tmp=dfs(r[f][u],f);
		val=((val*P)^tmp)%Q;
	}else{
		ULL tmp=(A&B^P);
		val=((val*P)^tmp)%Q;
	}
	if(!f) cnt[val]++;
	else ans+=cnt[val];
	return val;
}

int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		cnt.clear();
		ans=0;
		for(int i=1;i<=n;i++) scanf("%d%d",&l[0][i],&r[0][i]);
		for(int i=1;i<=m;i++) scanf("%d%d",&l[1][i],&r[1][i]);
		dfs(1,0);
		dfs(1,1);
		printf("%llu\n",ans);
	}
	return 0;
}
时间: 2024-08-13 18:14:48

ZOJ 3602 Count the Trees的相关文章

ZOJ 3602 Count the Trees 树的同构 (哈希)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4705 题意:给出两棵二叉树A和B,问分别处于A中的子树a和处于B中的子树b结构相同的有多少对. 思路:哈希的想法,不同的数字对应的是不同的结构,比如1代表着单独的叶子结点,2代表着有左子树是叶子结点而没有右子树的子树...每出现一种新的子树情形就记录下来,记录的方式是用dfs回溯过程中判断左子树和右子树组成的子树是否出现过(用pair记录子树的情况,也就是左右子树,两个

zjuoj 3602 Count the Trees

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3602 Count the Trees Time Limit: 2 Seconds      Memory Limit: 65536 KB A binary tree is a tree data structure in which each node has at most two child nodes, usually distinguished as "left&

zoj 1610 Count the Colors

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=610 先用线段树维护区间颜色的覆盖,然后在把区间的颜色映射到数组,再从数组统计颜色. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 100000 5 using namespace std; 6 7 int n; 8 int min1; 9

Count the Trees 典型卡特兰数

Count the Trees 题目分析:给你n个分别标为1,2,...,n的节点,问可以构成多少棵而叉树. 分析:首先考虑n个节点是相同的.任选一个节点做跟节点,那么剩下的n-1个节点构成跟节点的左子树和又子数. h[n] = h[0] * h[n-1] + h[1] * h[n - 2] + ... + h[n-1] * h[0];这正是卡特蓝表达式. h[n] = h[n-1] * (4 * n - 2) / (n + 1).   h[n] = C(2 * n,n)/(n + 1); 对于

UVa 10007 &amp; hdu 1131 Count the Trees (卡特兰数)

Count the Trees Time Limit:3000MS    Memory Limit:0KB     64bit IO Format:%lld & %llu SubmitStatus Description  Count the Trees  Another common social inability is known as ACM (Abnormally Compulsive Meditation). This psychological disorder is somewh

ZOJ 1610 Count the Colors (线段树区间更新)

题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头输出. //ZOJ 1610 #include <cstdio> #include <cstring> #include <iostream> using namespace std ; int p[8010*4],lz[8010*4] ,hashh[8010*4],has

zoj 1453 Surround the Trees(凸包求周长)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=453 Time Limit: 2 Seconds      Memory Limit: 65536 KB There are a lot of trees in an area. A peasant wants to buy a rope to surround all these trees. So at first he must know the minimal r

4292: Count the Trees(树hash)

4292: Count the Trees  时间限制(普通/Java):2000MS/6000MS     内存限制:65536KByte总提交: 15            测试通过:6 描述 A binary tree is a tree data structure in which each node has at most two child nodes, usually distinguished as "left" and "right". A su

zoj 1610 Count the Colors 【区间覆盖 求染色段】

Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can s