Codeforces Round 548(Div. 2)
A. Even Substrings
题目大意:
大概就是让你找到所有的偶数,然后让你累加这个偶数及之前的所有数的个数#include<bits/stdc++.h>
using namespace std;
const int MAXN = 65009;
int n, ans;
char s[MAXN];
int main()
{
cin >> n >> s + 1;
for (int i = 1; i <= n; i++) {
int x = s[i] - '0';
if (x % 2 == 0)ans += i;
}
cout << ans << endl;
return 0;
}
B. Chocolates
题目大意:
给你一个长度为n的序列,在每一位去取数字,每次取得的数要小于等于数列中的当前数,可以不取,最后取得的数列要求严格递增问能够取得的数列的和最大是多少
思路:
我们可以知道,最后取得的数一定是最大的数,所以我们倒着来取,如果要取的当前数小于已经取得最后一位数,我们就取当前数
若不小于,我们就取已经取得的最后一位数减一,这样可以满足取得的最大
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 10;
int main()
{
ios::sync_with_stdio(false); cin.tie();
int n, a[MAXN] = {0}, last = 0;
ll ans = 0;
cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
for (int i = n; i >= 1; i--) {
if (i == n || a[i] < last) {
ans += a[i];
last = a[i];
} else {
ans += max(0, last - 1);
last = max(0, last - 1);
}
}
cout << ans << endl;
return 0;
}
C. Edgy Trees
题目大意:
给你由n个顶点构成的一棵树,树的边分为红黑两种,由1和0代表,求经过k个顶点且至少有一条黑色的边的集合的个数,顶点可以重复取
思路:
直接求要求的集合的个数很难,我们可以先求出总数,为N^K个,然后减去经过k个顶点且不经过黑色的边的集合个数,是每个红色联通块
内的集合数之和,所以要求一下红色的联通块num,然后累加num^k即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int MAXN = 1e5 + 10;
ll ans, cnt;
int n, k, tot;
bool vis[MAXN];
vector<int>q[MAXN];
ll ksm(ll a, ll b)//快速幂
{
ll res = 1;
while (b) {
if (b & 1)res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void dfs(int u)//dfs求联通块
{
cnt++;
vis[u] = 1;
for (auto v : q[u])if (!vis[v]) {
dfs(v);
}
}
int main()
{
cin >> n >> k;
for (int i = 1; i < n; i++) {
int u, v, w;
cin >> u >> v >> w;
if (w == 0) {
q[u].push_back(v);
q[v].push_back(u);
}
}
ll ans = ksm(n, k);
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
cnt = 0;
dfs(i);
ans = (ans - ksm(cnt, k) + mod) % mod;
}
}
cout << ans << endl;
return 0;
}