牛客寒假集训营第一场 补题

I题nico和niconiconi

题目链接

很明显的dp,dp[i]表示前i个字符的最大值。输出dp[n]即可。

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
#include<iostream>
#include<stdio.h>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#define ll long long
#define lowbit(x)  (x)&(-x)
using namespace std;
template<class T>
void read(T& x)
{
	T res = 0, f = 1;
	char c = getchar();
	while (!isdigit(c))
	{
		if (c == '-')f = -1; c = getchar();
	}
	while (isdigit(c))
	{
		res = (res << 3) + (res << 1) + c - '0'; c = getchar();
	}
	x = res * f;
}
const ll N = 300000 + 20;
ll dp[N], n, a, b, c;
string s;
//1.是不是爆了int
int main()
{
	//ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
	freopen("182.txt", "r", stdin);
#endif // ONLINE_JUDGE
	read(n), read(a), read(b), read(c);
	cin >> s;
	for (int i = 0; i < s.size(); i++)
	{
		dp[i] = max(dp[max(i - 1,0)], dp[i]);
		string p1 = s.substr(i, 4);
		string p2 = s.substr(i, 6);
		string p3 = s.substr(i, 10);
		if (p1 == "nico")dp[i+3] = max(dp[i+3], dp[i] + a);
		if (p2== "niconi")dp[i+5] = max(dp[i+5], dp[i] + b);
		if (p3 == "niconiconi")dp[i+9] = max(dp[i+9], dp[i] + c);
	}
	printf("%lld", dp[n - 1]);
	return 0;
}

F题maki和tree

题目链接

路径只有一个黑点的情况有两种,一种是黑点端点,一种是两边端点都是白色中间有一个黑点。所以我们预处理出所有白点连通块中白点个数。对每一个黑点求出符合的路径。

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
#include<iostream>
#include<stdio.h>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#define ll long long
#define lowbit(x)  (x)&(-x)
using namespace std;
template<class T>
void read(T& x)
{
	T res = 0, f = 1;
	char c = getchar();
	while (!isdigit(c))
	{
		if (c == '-')f = -1; c = getchar();
	}
	while (isdigit(c))
	{
		res = (res << 3) + (res << 1) + c - '0'; c = getchar();
	}
	x = res * f;
}
const ll N = 100000 + 10;
ll n, head[N], sumline, dfn[N], lown[N], tag[N], cot, tot, sum[N], ans=0;
char col[N];
bool vis[N];
struct line
{
	int to, nxt;
}p[N*5];
void add(int a, int b)
{
	sumline++;
	p[sumline].nxt = head[a];
	head[a] = sumline;
	p[sumline].to = b;
}
stack<int>pls;
void tarjan(int u, int fa)
{
	dfn[u] = lown[u] = ++tot;
	vis[u] = 1;
	pls.push(u);
	for (int i = head[u]; i; i = p[i].nxt)
	{
		int to = p[i].to;
		if (col[to] == 'B')continue;
		if (!dfn[to])
		{
			tarjan(to, u);
			lown[u] = min(lown[u], lown[to]);
		}
		else if (vis[to])
			lown[u] = min(lown[u], dfn[to]);
	}
	if (lown[u] == dfn[u])
	{
		cot++;
		while (pls.top() != u)
		{
			tag[pls.top()] = cot;
			vis[pls.top()] = 0;
			pls.pop();
			sum[cot]++;
		}
		tag[pls.top()] = cot;
		vis[pls.top()] = 0;
		pls.pop();
		sum[cot]++;
	}
}
ll getans(vector<int>qls)
{
	ll sans = 0;
	ll sn = qls.size();
	ll tot = 0;
	for (int i = 0; i < sn; i++)
		tot+=qls[i];
	for (int i = 0; i < sn; i++)
	{
		sans += (tot - qls[i]) * qls[i];
	}
	sans /= 2;
	return sans + tot;
}
//1.是不是爆了int
int main()
{
	//ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
	freopen("182.txt", "r", stdin);
#endif // ONLINE_JUDGE
	read(n);
	scanf("%s", col + 1);
	for (int i = 1; i <= n - 1; i++)
	{
		int x, y;
		read(x), read(y);
		add(x, y);
		add(y, x);
	}
	for (int i = 1; i <= n; i++)
	{
		if (col[i] == 'W' && !dfn[i])
			tarjan(i, -1);
	}
	for (int i = 1; i <= n; i++)
	{
		if (col[i] == 'B')
		{
			vector<int>js;
			for (int j = head[i]; j; j = p[j].nxt)
			{
				if(col[p[j].to]=='W')
				js.push_back(sum[tag[p[j].to]]);
			}
			ans += getans(js);
		}
	}
	printf("%lld", ans);

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值