POJ 1470 & zoj 1141

被卡RE好久,原因是数组开的不够大

利用RMQ在线算法求解LCA,但是目前不知道为何POJ AC,but ZOJ TLE

ZOJ问题已修正,关于询问部分,输入格式与POJ不同,需要处理逗号

// use LCA->RMQ
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <utility>
#include <stack>
#include <vector>
#include <cmath>
#include <cassert>
using namespace std;

const int maxn= 9e2+3;

vector<vector<int> > fa;
int elsq[maxn<<1], depth[maxn<<1];
int fst[maxn];
int ST[maxn<<1][33];
int len;
int ans[maxn], dad[maxn];

void dfs(int u, int d)
{
	depth[u]= d;
	fst[u]= len;
	elsq[len++]= u;
	for (int i= 0; i< int(fa[u].size()); ++i){
		dfs(fa[u][i], d+1);
		elsq[len++]= u;
	}
}
inline int m_min(int a, int b)
{
	return depth[a] < depth[b] ? a : b;
}
void RMQ(void)
{
	int k= floor(log(len+0.0)/log(2.0));
	for (int i= 0; i< len; ++i){
		ST[i][0]= elsq[i];
	}
	for (int j= 1; j<= k; ++j){
		int step= 1<<(j-1), ub= len+1-(1<<j);
		for (int i= 0; i< ub; ++i){
			ST[i][j]= m_min(ST[i][j-1], ST[i+step][j-1]);
		}
	}
}
int Query(int l, int r)
{
	if (l> r){
		swap(l, r);
	}	
	int k= floor(log(r-l+1.0)/log(2.0));
	return m_min(ST[l][k], ST[r-(1<<k)+1][k]);
}
void Init(int n)
{
	fa.clear();
	fa.resize(n+5);
	memset(ans, 0, sizeof(ans));
	memset(dad, 0, sizeof(dad));
	memset(ST, 0, sizeof(ST));
	memset(fst, 0, sizeof(fst));
	memset(elsq, 0, sizeof(elsq));
	memset(depth, 0, sizeof(depth));
	len= 0;
}
int main(void)
{
	int n, nr, nq;
	int a, b, nd, snd;
	int rt;
	while (EOF!= scanf("%d", &n)){
		Init(n);
		for (int i= 0; i< n; ++i){
			scanf("%d: (%d)", &nd, &nr);
			for (int j= 0; j< nr; ++j){
				scanf("%d", &snd);
				fa[nd].push_back(snd);
				dad[snd]= 1;
			}
		
		}
		for (int i= 1; i<= n; ++i){
			if (0== dad[i]){
				rt= i;
				break;
			}
		}

		dfs(rt, 1);
		RMQ();

		scanf("%d", &nq);
		while (nq--){
			scanf(" (%d %d)", &a, &b);
			++ans[Query(fst[a], fst[b])];
		}


		for (int i= 1; i<= n; ++i){
			if (ans[i]){
				printf("%d:%d\n", i, ans[i]);
			}
		}

	}

	return 0;
}

ZOJ

// use LCA->RMQ
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <utility>
#include <stack>
#include <vector>
#include <cmath>
#include <cassert>
using namespace std;

const int maxn= 9e2+3;

vector<vector<int> > fa;
int elsq[maxn<<1], depth[maxn<<1];
int fst[maxn];
int ST[maxn<<1][33];
int len;
int ans[maxn], dad[maxn];

void dfs(int u, int d)
{
	depth[u]= d;
	fst[u]= len;
	elsq[len++]= u;
	for (int i= 0; i< int(fa[u].size()); ++i){
		dfs(fa[u][i], d+1);
		elsq[len++]= u;
	}
}
inline int m_min(int a, int b)
{
	return depth[a] < depth[b] ? a : b;
}
void RMQ(void)
{
	int k= floor(log(len+0.0)/log(2.0));
	for (int i= 0; i< len; ++i){
		ST[i][0]= elsq[i];
	}
	for (int j= 1; j<= k; ++j){
		int step= 1<<(j-1), ub= len+1-(1<<j);
		for (int i= 0; i< ub; ++i){
			ST[i][j]= m_min(ST[i][j-1], ST[i+step][j-1]);
		}
	}
}
int Query(int l, int r)
{
	if (l> r){
		swap(l, r);
	}	
	int k= floor(log(r-l+1.0)/log(2.0));
	return m_min(ST[l][k], ST[r-(1<<k)+1][k]);
}
void Init(int n)
{
	fa.clear();
	fa.resize(n+5);
	memset(ans, 0, sizeof(ans));
	memset(dad, 0, sizeof(dad));
	memset(ST, 0, sizeof(ST));
	memset(fst, 0, sizeof(fst));
	memset(elsq, 0, sizeof(elsq));
	memset(depth, 0, sizeof(depth));
	len= 0;
}
int main(void)
{
	int n, nr, nq;
	int a, b, nd, snd;
	int rt;
	while (EOF!= scanf("%d", &n)){
		Init(n);
		for (int i= 0; i< n; ++i){
			scanf("%d: (%d)", &nd, &nr);
			for (int j= 0; j< nr; ++j){
				scanf("%d", &snd);
				fa[nd].push_back(snd);
				dad[snd]= 1;
			}
		
		}
		for (int i= 1; i<= n; ++i){
			if (0== dad[i]){
				rt= i;
				break;
			}
		}

		dfs(rt, 1);
		RMQ();

		scanf("%d", &nq);
		while (nq--){
			scanf(" (%d,%d)", &a, &b);
			++ans[Query(fst[a], fst[b])];
		}


		for (int i= 1; i<= n; ++i){
			if (ans[i]){
				printf("%d:%d\n", i, ans[i]);
			}
		}

	}

	return 0;
}
posted @ 2020-03-28 18:11  IdiotNe  阅读(109)  评论(0编辑  收藏  举报