列表

详情


NC15420. Perfect N-P Arrays

描述

Define a particular type of arrays as perfect if:

For example, the following arrays are perfect:

While the followings are not:

The NP-value of a perfect array is the maximum prefix sum occurred in the array. For example, the NP-values of the two perfect arrays above are 3 and 2 respectively.

Given a tree with either -1 or 1 assigned on each node, please figure out a simple path, that the array concatenated by values on the path is perfect along with the maximum NP-value.

输入描述

The input consists of multiple test cases.

Each test case begins with an integer n (1 ≤ n ≤ 106), the number of nodes in the tree.

Then n lines follow. The i-th line of the following n lines consists of fi (0 ≤ fi ≤ n) and vi (vi ∈ {-1, 1}), which respectively denotes the parent node and the assigned value of the i-th node. Nodes are labeled from 1 to n, and fi = 0 indicates that node i is a root.

The sum of n in all test cases does not exceed 5 × 106.

输出描述

For each test case, output the maximum NP-value found on the tree. Output 0 if such path doesn't exist.

示例1

输入:

5
0 -1
1 1
1 -1
2 1
2 -1

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 2140ms, 内存消耗: 131204K, 提交时间: 2019-01-10 20:52:05

#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<algorithm>
inline int getint() {
	register char ch;
	register bool neg=false;
	while(!isdigit(ch=getchar())) neg|=ch=='-';
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return neg?-x:x;
}
const int N=2e6+1;
std::vector<int> e[N];
int w[N],ans,max[N][2],min[N][2];
inline void add_edge(const int &u,const int &v) {
	e[u].push_back(v);
	e[v].push_back(u);
}
inline void upd1(const int &x,const int &y) {
	int tmp1=min[y][0]+w[x];
	int tmp2=max[y][0]+w[x];
	for(register int i=0;i<2;i++) {
		if(tmp1<min[x][i]) {
			std::swap(tmp1,min[x][i]);
		}
		if(tmp2>max[x][i]) {
			std::swap(tmp2,max[x][i]);
		}
	}
}
inline void upd2(const int &x,const int &y) {
	int tmp1=min[y][min[y][0]==min[x][0]+w[y]];
	int tmp2=max[y][max[y][0]==max[x][0]+w[y]];
	if(tmp1!=INT_MAX) tmp1+=w[x];
	if(tmp2!=INT_MIN) tmp2+=w[x];
	for(register int i=0;i<2;i++) {
		if(tmp1!=INT_MAX&&tmp1<min[x][i]) {
			std::swap(tmp1,min[x][i]);
		}
		if(tmp2!=INT_MIN&&tmp2>max[x][i]) {
			std::swap(tmp2,max[x][i]);
		}
	}
}
void dfs1(const int &x,const int &par) {
	max[x][0]=min[x][0]=w[x];
	max[x][1]=INT_MIN;
	min[x][1]=INT_MAX;
	for(auto &y:e[x]) {
		if(y==par) continue;
		dfs1(y,x);
		upd1(x,y);
	}
}
void dfs2(const int &x,const int &par) {
	for(auto &y:e[x]) {
		if(y==par) continue;
		ans=std::max(ans,std::min(std::abs(max[y][0]),std::abs(min[x][min[x][0]==min[y][0]+w[x]])));
		ans=std::max(ans,std::min(std::abs(min[y][0]),std::abs(max[x][max[x][0]==max[y][0]+w[x]])));
		upd2(y,x);
		dfs2(y,x);
	}
}
int main() {
	int n;
	while(~scanf("%d",&n)) {
		for(register int i=1;i<=n;i++) {
			const int p=getint();
			if(p) add_edge(p,i);
			w[i]=getint();
		}
		dfs1(1,0);
		dfs2(1,0);
		printf("%d\n",ans);
		for(register int i=1;i<=n;i++) {
			e[i].clear();
		}
		ans=0;
	}
	return 0;
}

上一题