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;
}