CodeForces - 1529C
容易发现,每个点的权值只会取 L L L或者 R R R。 D P [ i ] [ 0 / 1 ] DP[i][0/1] DP[i][0/1]表示根节点 i i i取 L / R L/R L/R时,子树的最大权值。
代码
#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 5;
long long L[N], R[N];
vector<long long> vec[N];
long long dp[N][2];
void dfs(long long u, long long pre)
{
for (auto v : vec[u])
{
if (v == pre)
continue;
dfs(v, u);
dp[u][0] += max(abs(L[u] - L[v]) + dp[v][0], abs(L[u] - R[v]) + dp[v][1]);
dp[u][1] += max(abs(R[u] - L[v]) + dp[v][0], abs(R[u] - R[v]) + dp[v][1]);
}
}
int main()
{
long long t;
cin >> t;
while (t--)
{
memset(dp, 0, sizeof dp);
long long n;
cin >> n;
for (int i = 1; i <= n; i++)
vec[i].clear();
for (int i = 1; i <= n; i++)
scanf("%lld %lld", &L[i], &R[i]);
for (int i = 1; i < n; i++)
{
long long u, v;
scanf("%lld %lld", &u, &v);
vec[u].emplace_back(v);
vec[v].emplace_back(u);
}
dfs(1, -1);
cout << '\t' << max(dp[1][0], dp[1][1]) << endl;
}
return 0;
}
牛客多校第六场I
无论什么情况都可以构造。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N];
int n, m;
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d %d", &n, &m);
for (int i = 0; i <= n + 1; i++)
a[i] = 0;
for (int i = 1; i <= m; i++)
{
int l, r;
scanf("%d %d", &l, &r);
if (l <= r)
{
a[l]++;
a[r + 1]--;
}
else
{
a[l]++;
a[n + 1]--;
a[1]++;
a[r + 1]--;
}
}
for (int i = 1; i <= n; i++)
a[i] += a[i - 1];
vector<pair<int, int>> vec;
int l, r, flag = 0;
a[n + 1] = 0;
for (int i = 1; i <= n + 1; i++)
{
if (a[i])
{
if (!flag)
{
flag = 1;
l = i;
}
}
else
{
if (flag)
{
vec.emplace_back(make_pair(l, i - 1));
flag = 0;
}
}
}
if (vec[0].first == 0 && vec[vec.size() - 1].second == n)
{
vec[0].first = vec[vec.size() - 1].first;
vec.pop_back();
}
int len = vec.size();
cout << len << endl;
cout << vec[0].first << ' ' << vec[len - 1].second << endl;
for (int i = 1; i < len; i++)
cout << vec[i].first << ' ' << vec[i - 1].second << endl;
cout << endl;
}
return 0;
}
牛客多校第六场F
每个牛排至少要独立花费 T i T_i Ti的时间,使用一次交换机会可以让所有锅都尽可能利用上。
因此,最小花费时间为 m a x ( M A X T i , A D V T i ) max(MAX_{T_i},ADV_{T_i}) max(MAXTi,ADVTi)
有了最小花费时间,即可贪心构造。
代码
#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 5;
long long a[N];
int main()
{
long long n, m;
cin >> n >> m;
long long T = 0, mx = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mx = max(mx, 1ll * a[i]);
T += a[i];
}
T = max(mx, T / m + (T % m ? 1 : 0));
long long id = 1, l = 0;
for (int i = 1; i <= n; i++)
{
if (a[i] + l <= T)
cout << 1 << ' ' << id << ' ' << l << ' ' << (l += a[i], l) << endl;
else
{
vector<pair<long long , pair<long long , long long >>> vec;
vec.emplace_back(make_pair(l, make_pair(T, id)));
vec.emplace_back(make_pair(0, make_pair(a[i] - (T - l), id + 1)));
++id, l = a[i] - (T - l);
sort(vec.begin(), vec.end());
cout << 2 << ' ' << vec[0].second.second << ' ' << vec[0].first << ' ' << vec[0].second.first;
cout << ' ' << vec[1].second.second << ' ' << vec[1].first << ' ' << vec[1].second.first << endl;
}
if (l == T)
++id, l = 0;
}
return 0;
}
CodeForces - 1549D
对于 n n n个数存在数 m m m,使得 n n n个数模 m m m的值相同,可以转化为,对 n n n个数做差分,差分后的数取模 m m m为 0 0 0。
这样,只要差分后的区间 g c d gcd gcd不为1,就存在一个 m m m。
区间 g c d gcd gcd可以用 r m q rmq rmq维护。
注意n=1等特殊情况。
下面的代码是没用rmq瞎搞的,感觉挺对,小数据(n<=100)暴力就能AC
代码
#include <bits/stdc++.h>
using namespace std;
const long long N = 2e5 + 10;
long long a[N];
long long b[N];
bool vis[N];
int main()
{
long long t;
cin >> t;
while (t--)
{
long long n;
scanf("%lld", &n);
for (int i = 0; i <= n + 1; i++)
vis[i] = 0;
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
if (n == 1)
{
cout << 1 << endl;
continue;
}
for (int i = 2; i <= n; i++)
{
b[i] = abs(a[i] - a[i - 1]);
}
long long ans = 0;
for (int i = 2; i <= n; i++)
{
long long pos = i;
if ((n >= 100 && vis[pos]) || b[pos] == 1)
{
ans = max(ans, 1ll);
continue;
}
long long sum = 2;
long long g = b[pos];
for (int i = pos + 1; i <= n; i++)
{
long long tmpg = __gcd(g, 1ll * b[i]);
if (tmpg == 1)
break;
g = tmpg;
vis[i] = 1;
sum++;
}
for (int i = pos - 1; i >= 2; i--)
{
g = __gcd(g, 1ll * b[i]);
if (g == 1)
break;
vis[i] = 1;
sum++;
}
ans = max(ans, sum);
}
cout << ans << endl;
}
return 0;
}
本文解析了CodeForces平台上的几道经典算法题目,包括树形DP、构造算法及贪心策略的应用。通过示例代码详细介绍了如何求解最大权值、构造特定序列以及优化烹饪时间等问题。
429

被折叠的 条评论
为什么被折叠?



