Codeforces Round #527 (Div. 3)D,F;

D题:是一个思维题,同时也是一个数据结构,首先要知道什么情况对,是否可以添加到一个高度有影响,首先想到的是就是如果两个数相邻,且他们相差为奇数,这是就不可以叠到一样高,但是如果2, 1, 1这种情况就可以所以如果奇数出现,偶数次且相邻这是就可以平成任意的高度,这是这两个柱子就不需要考虑。可以消掉,这是·就继续往下考虑;这就相当于一个栈的结构。

从这里可以知道,奇数对是否成功有影响,1,3,5他们都是等价的所以都变为1, 也就是对所有的书对二取余,预处理之后就开始站的操作,如果压入栈中的数再次出现,且等于s.top(),这是就是这个数pop()除去,不断进行这样的操作,最后判断栈中的数的个数,如果大于1就是输出“NO”,否则输出“YES”;

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n;
stack<int>s;
int main(){
	ios::sync_with_stdio(false);
	cin >> n;
	int a;
	while(n--){
		cin >> a;
		a = a%2;
		if(s.size() > 0 && s.top() == a){
			s.pop();
		}else s.push(a);
	}
	if(s.size() > 1)cout << "NO"<< endl;
	else cout << "YES" << endl;
	return 0;
}

F题是一道关于树的题目:也就是数据结构啊,在做题时要考虑到树的基本结构,然后要对树有敏感,对有关树的操作熟悉,有哪些关于树的题型,和什么算法是以树为基础的,一般的就会有线段树,搜索等等,对于此题首先要如何确定更节点,是每个都尝试一遍还是通过以某一点为基础,来转化其他的点,最后取最值,首先如果暴力的话就要求时间复杂的高,所以可以舍去,那么就应该第二种方法。这是就要求对树有深刻的认识,知道他们之间的联系,又题意可知要求某一点的值乘以边的个数,那么可不可以把乘法转化为加法,这样是不是就可以使用深度搜索,不断更新,求和,=最后得出一点到值,然后在通过转化来求出最值。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 2e5 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
ll n;
ll a[maxn];//初始化
ll s[maxn];//求每个节点下的值
ll d[maxn];//乘积关系的转化 
vector<ll>v[maxn];
ll k, r;
ll dfs1(int x, int y){
	s[x] = a[x];
	for(int i =0; i < v[x].size(); i ++ ){
		if(v[x][i]!=y){
			s[x] += dfs1(v[x][i], x);
			d[x] += d[v[x][i]] + s[v[x][i]];
		}
	}
	return s[x];
}

void dfs(int x, int y, ll c){
	c += k - s[x]*2;
	r = max(r,c);
	for(int i =0; i < v[x].size(); i++){
		if(v[x][i] != y){
			dfs(v[x][i],x,c);
		}
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin >> n;
	for(int i = 1; i <= n; i ++)cin >> a[i];
	ll x, y;
	for(int i = 1; i < n ; i++){
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	k = dfs1(1,1);
	//cout << k << endl;
	r = d[1];
	//cout << r << endl;
	ll t = k + r;
	dfs(1,1,t);
	cout << r << endl;
	return 0;
}

还有很长的路要走,继续加油。

猜你喜欢

转载自blog.csdn.net/ab1605014317/article/details/85199580