Codeforces Round #263 (Div. 2)

A.Appleman and Easy Task

题意:求是否所有格子周围都有偶数个'o'

题解:暴力遍历即可。

B.Appleman and Card Game

题意:一个人有n个卡片,每个卡片上面有一个英文大写字母。另一个人从中取k张,每张卡片的价值是取出同种卡片的数量。

题解:统计每种卡片出现次数,排序从数量多的开始取。hack点为爆int。

C.Appleman and Toastman

题意:给出一个集合包含n个数,进行两种操作。一种是:将集合给A,集合内所有数的和加到结果中,将集合给B。另一种是:如果B接到的集合只含一个元素,丢弃。否则将集合任意分成两份,分别给A。求最大结果。

题解:画了几种情况发现每次去掉最小的结果最大。写了,过了。

代码:

D.Appleman and Tree

题意:一棵树,顶点分为黑白两种。删去一些边,使得形成的每棵新树有且只有一个黑点。求删边的可能数。

官方题解:

Fill a DP table such as the following bottom-up:

DP[v][0] = the number of ways that the subtree rooted at vertex v has no black vertex.
DP[v][1] = the number of ways that the subtree rooted at vertex v has one black vertex.
The recursion pseudo code is folloing:

DFS(v):
 DP[v][0] = 1
 DP[v][1] = 0
 foreach u : the children of vertex v
  DFS(u)
  DP[v][1] *= DP[u][0]
  DP[v][1] += DP[v][0]*DP[u][1]
  DP[v][0] *= DP[u][0]
 if x[v] == 1:
  DP[v][1] = DP[v][0]
 else:
  DP[v][0] += DP[v][1]
The answer is DP[root][1].

PS:当时只推出了dp[v][1] *= dp[u][0];后面说什么也没推出来,太弱啊……

代码:

//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖保佑             永无BUG 
//          佛曰:  
//                  写字楼里写字间,写字间里程序员;  
//                  程序人员写程序,又拿程序换酒钱。  
//                  酒醒只在网上坐,酒醉还来网下眠;  
//                  酒醉酒醒日复日,网上网下年复年。  
//                  但愿老死电脑间,不愿鞠躬老板前;  
//                  奔驰宝马贵者趣,公交自行程序员。  
//                  别人笑我忒疯癫,我笑自己命太贱;  
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define For(i,a) for(i=0;i=b;i--)
#define clr(ar,vel) memset(ar,vel,sizeof(ar))
#define PB push_back
typedef long long ll;
const int maxint = 0x7fffffff;
const ll maxll = 1LL<<60;
const int mod = 1000000007;
const double EPS = 1e-10;
vector vi[100010];
int vel[100010], vis[100010];
int dp[100010][2];		//0:不全脱离 ;   1:全脱离; 
inline int dfs(int n){
//	cout << n << endl;
	int flag = 0;
	ll zero = 1, one = 0;
	
	for(int i = 0; i < vi[n].size(); i ++){
		int nxt = vi[n][i];
		if( vis[nxt] ) continue;
		vis[nxt] = 1;
		dfs( nxt );
		one *= dp[nxt][0];
		one += zero*dp[nxt][1];
		zero *= dp[nxt][0];
		one %= mod;
		zero %= mod;
	}
	dp[n][0] = zero;
	dp[n][1] = one; 
	if( vel[n]) dp[n][1] = dp[n][0];
	else dp[n][0] += dp[n][1];
	dp[n][1] %= mod;
	dp[n][0] %= mod;
}
int main(){
	int n;
	cin >> n;
	memset(vis, 0, sizeof(vis));
	memset(dp, 0, sizeof(dp));
	for(int i = 0; i < n; i ++) vi[i].clear();
	for(int i = 1, x; i < n; i ++){
		cin >> x;
		vi[x].push_back(i);
//		vi[i].push_back(x);    一开始建的无向边,wa了   看人家都是有向的注销了,过了
	}
	for(int i = 0; i < n; i ++) cin >> vel[i];
	dfs(0);
//	cout << "can solve" << endl;
	cout << dp[0][1]%mod << endl; 
	
	return 0;
}



你可能感兴趣的:(contest,CF)