CodeForces Gym 102055 简要题解

Mischievous Problem Setter模拟。#include <bits/stdc++.h>using namespace std;int main() {#ifdef wxh010910 freopen("input.txt", "r", stdin);#endif ios::sync_with_stdio(false); cin.tie(0...
摘要由CSDN通过智能技术生成

Mischievous Problem Setter

模拟。

#include <bits/stdc++.h>

using namespace std;

int main() {
   
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int tt;
  cin >> tt;
  for (int qq = 1; qq <= tt; ++qq) {
   
    int n, m;
    cin >> n >> m;
    vector<pair<int, int>> a(n);
    for (int i = 0; i < n; ++i) {
   
      cin >> a[i].first;
    }
    for (int i = 0; i < n; ++i) {
   
      cin >> a[i].second;
    }
    sort(a.begin(), a.end());
    int ans = 0;
    while (ans < n && m >= a[ans].second) {
   
      m -= a[ans++].second;
    }
    cout << "Case " << qq << ": " << ans << "\n";
  }
  return 0;
}

Balance of the Force

建出图,如果图不是二分图,则无解。否则枚举最大值,用堆维护最小值的最大可能值。

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

class heap {
   
  priority_queue<int, vector<int>, greater<int>> p, q;

 public:
  void push(int x) {
   
    p.push(x);
  }

  void pop(int x) {
   
    q.push(x);
  }

  int top() {
   
    while (!q.empty() && p.top() == q.top()) {
   
      p.pop();
      q.pop();
    }
    return p.top();
  }
};

int main() {
   
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int tt;
  cin >> tt;
  for (int qq = 1; qq <= tt; ++qq) {
   
    int n, m;
    cin >> n >> m;
    vector<vector<int>> adj(n);
    for (int i = 0; i < m; ++i) {
   
      int from, to;
      cin >> from >> to;
      --from;
      --to;
      adj[from].push_back(to);
      adj[to].push_back(from);
    }
    vector<vector<int>> a(n, vector<int>(2));
    for (int i = 0; i < n; ++i) {
   
      cin >> a[i][0] >> a[i][1];
    }
    bool no_solution = false;
    vector<int> sz(n);
    vector<int> cur(n);
    vector<int> min_id(n);
    vector<int> color(n, -1);
    vector<vector<int>> cnt(n, vector<int>(2));
    vector<vector<int>> minv(n, vector<int>(2, inf));
    heap h;
    for (int i = 0; i < n; ++i) {
   
      if (color[i] == -1) {
   
        h.push(cur[i] = -inf);
        queue<int> q;
        color[i] = 0;
        min_id[i] = i;
        ++sz[i];
        q.push(i);
        while (!q.empty()) {
   
          int x = q.front();
          q.pop();
          minv[i][color[x]] = min(minv[i][color[x]], a[x][0]);
          minv[i][!color[x]] = min(minv[i][!color[x]], a[x][1]);
          for (auto y : adj[x]) {
   
            if (color[y] == -1) {
   
              color[y] = !color[x];
              min_id[y] = i;
              ++sz[i];
              q.push(y);
            } else if (color[y] == color[x]) {
   
              no_solution = true;
              break;
            }
          }
        }
        if (no_solution) {
   
          break;
        }
      }
    }
    if (no_solution) {
   
      cout << "Case " << qq << ": IMPOSSIBLE" << "\n";
      continue;
    }
    int ans = inf;
    vector<pair<int, int>> events(n * 2);
    for (int i = 0; i < n; ++i) {
   
      events[i * 2] = make_pair(a[i][0], i);
      events[i * 2 + 1] = make_pair(a[i][1], i + n);
    }
    sort(events.begin(), events.end());
    for (auto p : events) {
   
      int x = p.second;
      if (x >= n) {
   
        x -= n;
        if (++cnt[min_id[x]][!color[x]] == sz[min_id[x]]) {
   
          h.pop(cur[min_id[x]]);
          cur[min_id[x]] = max(cur[min_id[x]], minv[min_id[x]][!color[x]]);
          h.push(cur[min_id[x]]);
        }
      } else {
   
        if (++cnt[min_id[x]][color[x]] == sz[min_id[x]]) {
   
          h.pop(cur[min_id[x]]);
          cur[min_id[x]] = max(cur[min_id[x]], minv[min_id[x]][color[x]]);
          h.push(cur[min_id[x]]);
        }
      }
      ans = min(ans, p.first - h.top());
    }
    cout << "Case " << qq << ": " << ans << "\n";
  }
  return 0;
}

GCD Land

m m m n 2 \frac{n}{2} 2n ,令 m m m 的编号 x x x 为不超过 m m m 的素数的乘积,那么此时只有 m + 1 m+1 m+1 m − 1 m-1 m1 没有连起来;考虑去掉 m m m 以内的最大的两个质数 p , q p, q p,q ,用它们去连 1 1 1 − 1 -1 1 (即 x − 1 &VeryThinSpace; m o d &VeryThinSpace; p = 0 , x + 1 &VeryThinSpace; m o d &VeryThinSpace; q = 0 x-1\bmod p=0, x+1\bmod q=0 x1modp=0,x+1modq=0 ),此时 m − p , m − q , m + p , m + q m-p, m-q, m+p, m+q mp,mq,m+p,m+q 没有被连起来;注意到我们还没有用大于 m m m 的质数,用这些质数连起来,最后CRT合并即可。这个做法需要特判 n ≤ 38 n\le 38 n38 的数据。

to_multiply = []
table = [-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2183, 27828, 27827, 87889, 87889, 171053, 171053, 323509, 127373, 323509, 151061, 151061, 151061, 151060, 151059, 151058, 151057, 672540170261, 672540170261, 2101641443861, 2101641443861, 4152621523030]

def inv(a, md):
    b, u, v = md, 0, 1
    while a:
        t = b / a
        a, b = b - t * a, a
        v, u = u - t * v, v
    if u < 0:
        u += md
    return u

def crt(m, a):
    mm, aa = m[0], a[0]
    for i in range(1, len(m)):
        mm, aa = mm * m[i], (aa * m[i] * inv(m[i], mm) + a[i] * mm * inv(mm, m[i])) % (mm * m[i])
    return aa

def multiply_all(l, r):
    if l > r:
        return 1
    elif l == r:
        return to_multiply[l]
    else:
        m = (l + r) / 2
        return multiply_all(l, m) * multiply_all(m + 1, r)

tt = int(raw_input())
for qq in range(1, tt + 1):
    n = int(raw_input())
    if n < 39:
        ans = table[n]
    else:
        prime = [True] * (n + 1)
        for i in range(2, n + 1):
            for j in range(i + i, n + 1, i):
                prime[j] = False
        m = (n + 1) / 2
        to_multiply = []
        for i in range(2, m):
            if prime[i]:
                to_multiply.append(i)
        p, q = to_multiply[-2], to_multiply[-1]
        to_multiply = to_multiply[:-2]
        if m * 2 == n and prime[m]:
            to_multiply.append(m)
        r = []
        for i in range(n - m + 1, n):
            if prime
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值