1001. tree
题意
一棵根为1的树,要求选择两个节点加一条单向边,使得的二元组数量最多
思路
从一个点出发可以到达他的所有子节点和他自己,添加一条边使得(x,y)(从x到y)最多,添加的这条边的终点最好的情况就是连一个子节点最多的点,也就是直接连到根节点1是最优的情况
第一次搜索,用来记录未加边时
用dept记录深度,dp记录元组数,sum记录元组和
第二次搜索,用来记录加边后重复元组的数量
n * dept - tt 为增量
代码
/*************************************************************************
> FileName:
> Author: Lance
> Mail: lancelot_hcs@qq.com
> Date: 9102.1.8
> Description:
************************************************************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int mod = 1e9 + 7;
#define debug(a) cout << "*" << a << "*" << endl
const int INF = 0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
const int maxn = 500005;
//sacnf("%lf") printf("%f")
ll read()
{
ll x = 0,f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll t, n;
vector<ll> G[maxn];
ll dp[maxn];
ll dept[maxn];
ll tt[maxn], sum = 0;
void dfs(int x, int fa) {
if (x == 1) dept[x] = 1;
else dept[x] = dept[fa] + 1;
dp[x] = 1;
for (int i = 0; i < G[x].size(); i++) {
int tem = G[x][i];
if (tem != fa) {
dfs(tem, x);
dp[x] += dp[tem];
}
}
sum += dp[x];
}
void dfs1(int x, int fa) {
tt[x] = tt[fa] + dp[x];
for (int i = 0; i < G[x].size(); i++) {
int tem = G[x][i];
if (tem != fa) {
dfs1(tem, x);
}
}
}
void solve()
{
t = read();
while (t--) {
sum = 0;
n = read();
int a;
for (int i = 2; i <= n; i++) {
a = read();
G[a].push_back(i);
}
dfs(1, 0);
dfs1(1, 0);
ll max_ = -INF, index = 0;
for (int i = 1; i <= n; i++) {
max_ = max(max_, n * dept[i] - tt[i]);
}
printf("%lld
", sum + max_);
for (int i = 1; i <= n; i++) {
G[i].clear();
dp[i] = 0;
dept[i] = 0;
tt[i] = 0;
}
}
}
int main()
{
// freopen("F:/Overflow/in.txt","r",stdin);
// ios::sync_with_stdio(false);
solve();
return 0;
}
1003. Slime and Stones
题意
威尔逊博弈的拓展, 威佐夫博弈是本题的k = 0 的情况
思路
待续
代码
///*************************************************************************
// > FileName:
// > Author: Lance
// > Mail: lancelot_hcs@qq.com
// > Date: 9102.1.8
// > Description:
// ************************************************************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int mod = 1e9 + 7;
#define debug(a) cout << "*" << a << "*" << endl
const int INF = 0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
const int maxn = 1000005;
//sacnf("%lf") printf("%f")
ll read()
{
ll x = 0,f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll t, n, a, b, k;
void solve()
{
t =read();
while (t--) {
a = read(), b = read(), k = read();
if (a > b) {
swap(a, b);
}
k++;
n = b - a;
if (n % k) {
puts("1");
continue;
} else {
if (int(n * ((2 - k) * 1ll + sqrt(k * k * 1.0 + 4.0)) / 2 / k) == a) {
puts("0");
} else {
puts("1");
}
}
}
}
int main()
{
// freopen("F:/Overflow/in.txt","r",stdin);
// ios::sync_with_stdio(false);
solve();
return 0;
}