TAP

GYM 105321 N

题目描述

一个长宽高分别为 \(a,b,c\) 的代价为 \(ab+ac+bc\),价值为 \(a^2+b^2+c^2\),其收益为价值减代价。给定可选的长宽高 \(V_i\),求最大收益。

思路

直接拆式子:

\[\begin{array}{l} a^2+b^2+c^2-ab-ac-bc\\ =\frac{1}{2}(a^2+a^2+b^2+b^2+c^2+c^2-2ab-2ac-2bc)\\ =\frac{1}{2}((a^2-2ab+b^2)+(a^2-2ac+c^2)+(b^2-2bc+c^2))\\ =\frac{1}{2}((a-b)^2+(a-c)^2+(b-c)^2) \end{array} \]

以上这个式子很明显 \(a\) 越大越好,\(c\) 越小越好,所以让 \(a,c\) 分别取最大值,最小值,并枚举 \(b\) 即可。

时空复杂度均为 \(O(N)\)

代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXN = 5001;

int n, a[MAXN], Min = 1000001, Max;
ll ans;

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n;
  for(int i = 1; i <= n; ++i) {
    cin >> a[i];
    Min = min(Min, a[i]), Max = max(Max, a[i]);
  }
  for(int i = 1; i <= n; ++i) {
    ans = max(ans, (1ll * (Min - a[i]) * (Min - a[i]) + 1ll * (Min - Max) * (Min - Max) + 1ll * (a[i] - Max) * (a[i] - Max)) / 2);
  }
  cout << ans;
  return 0;
}

GYM 105321 H

题目描述

\(N\) 个矩形围栏,这些围栏没有点相交。有 \(M\) 个降落点,有两个人将等概率地落在这些降落点上。求它们要走到一起总共需要穿越围栏数的期望值。

思路

显然要穿过一个栅栏当且仅当一个人在栅栏里,另一个人在栅栏外。所以我们只需统计栅栏里的降落点数量并计算即可。也就是二维数点。

空间复杂度 \(O(N+M)\),时间复杂度 \(O((N+M)\log (N+M))\)

代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXN = 200001;

struct Node {
  int x, y, x2, y2;
}a[MAXN];

struct node {
  int x, y;
}b[MAXN];

int n, m, X[3 * MAXN], Y[3 * MAXN], tot, tot2, tr[3 * MAXN], ans[MAXN];
ll Ans;
vector<tuple<int, int, int, int>> ve[3 * MAXN];
vector<int> vec[3 * MAXN];

int lowbit(int x) {
  return x & -x;
}

void update(int p, int x) {
  for(; p <= 2 * n + m; tr[p] += x, p += lowbit(p)) {
  }
}

int Getsum(int p) {
  int sum = 0;
  for(; p; sum += tr[p], p -= lowbit(p)) {
  }
  return sum;
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for(int i = 1; i <= n; ++i) {
    cin >> a[i].x >> a[i].y >> a[i].x2 >> a[i].y2;
    X[i] = a[i].x, X[n + i] = a[i].x2;
    Y[i] = a[i].y, Y[n + i] = a[i].y2;
  }
  for(int i = 1; i <= m; ++i) {
    cin >> b[i].x >> b[i].y;
    X[2 * n + i] = b[i].x, Y[2 * n + i] = b[i].y;
  }
  sort(X + 1, X + 2 * n + m + 1);
  sort(Y + 1, Y + 2 * n + m + 1);
  for(int i = 1; i <= 2 * n + m; ++i) {
    if(!tot || X[i] > X[tot]) {
      X[++tot] = X[i];
    }
  }
  for(int i = 1; i <= 2 * n + m; ++i) {
    if(!tot2 || Y[i] > Y[tot2]) {
      Y[++tot2]= Y[i];
    }
  }
  for(int i = 1; i <= n; ++i) {
    a[i].x = lower_bound(X + 1, X + tot + 1, a[i].x) - X;
    a[i].x2 = lower_bound(X + 1, X + tot + 1, a[i].x2) - X;
    a[i].y = lower_bound(Y + 1, Y + tot2 + 1, a[i].y) - Y;
    a[i].y2 = lower_bound(Y + 1, Y + tot2 + 1, a[i].y2) - Y;
    ve[a[i].x - 1].emplace_back(a[i].y, a[i].y2, -1, i);
    ve[a[i].x2].emplace_back(a[i].y, a[i].y2, 1, i);
  }
  for(int i = 1; i <= m; ++i) {
    b[i].x = lower_bound(X + 1, X + tot + 1, b[i].x) - X;
    b[i].y = lower_bound(Y + 1, Y + tot2 + 1, b[i].y) - Y;
    vec[b[i].x].push_back(b[i].y);
  }
  for(int i = 1; i <= 2 * n + m; ++i) {
    for(int x : vec[i]) {
      update(x, 1);
    }
    for(auto [l, r, x, id] : ve[i]) {
      ans[id] += x * (Getsum(r) - Getsum(l - 1));
    }
  }
  for(int i = 1; i <= n; ++i) {
    Ans += 2ll * ans[i] * (m - ans[i]);
  }
  cout << fixed << setprecision(9) << 1.0l * Ans / (1.0l * m * m);
  return 0;
}
posted @ 2024-09-28 14:47  Yaosicheng124  阅读(3)  评论(0编辑  收藏  举报