Codeforces Global Round 27

Luckyblock發表於2024-10-28

目錄
  • 寫在前面
  • A 簽到
  • B 結論
  • C 構造
  • D 貪心,單調棧
  • E 結論,數論分塊
  • 寫在最後

寫在前面

比賽地址:https://codeforces.com/contest/2035

前期犯唐 C 不會呃呃,後面 E 會了然而跑去寫什麼狗屁三分似掉了也沒救回來。

本來想著一場上橙的,這下又掉分了哈哈。

厭學中。

A 簽到

發現受到影響的位置僅有三種:

  • 在第 \(r\) 行,\(c+1\sim m\) 列的,左移一位;
  • 在第 \(r+1\sim n\) 行,第 1 列的,移動到上一行最後;
  • 在第 \(r+1\sim n\) 行,第 \(2\sim m\) 列的,左移一位。

三種位置的貢獻求和即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    int n, m, r, c; std::cin >> n >> m >> r >> c;
    LL ans = 0;
    ans += 1ll * (m - c);
    ans += 1ll * (n - r) * (m - 1 + 1);
    ans += 1ll * (n - r) * 1 * (m - 1);
    std::cout << ans << "\n";
  }
  return 0;
}

B 結論

顯然僅需考慮模 66 為 0。

一個顯然的想法是先構造為全 3 的數,然後把某些位改成 6。

打了個表發現對於全 3 的數,模 66 的餘數只有 3 和 33 兩種情況,於是根據樣例:

  • 若餘數為 33,考慮再加 33,即將後兩位改成 6 即可;
  • 若餘數為 3,考慮再加 3033 即可。

若無法加則無解。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;

  while (T --) {
    int n; std::cin >> n;
    std::string ans;
    LL sum = 0;
    for (int i = 1; i <= n; ++ i) ans.push_back('3'), sum = (10 * sum + 3) % 66;

    if (sum == 33) {
      ans[n - 1] = '6', ans[n - 2] = '6';
    } else {
      if (n == 1 || n == 3) ans = "-1";
      else ans[n - 1] = '6', ans[n - 2] = '6', ans[n - 4] = '6';
    }
    std::cout << ans << "\n";
  }
  return 0;
}

C 構造

媽的不會構造被鯊了。

首先透過樣例猜測,當 \(n\) 為奇數時 \(k=n\)\(n\) 為偶數時 \(k = 2^{\left\lfloor\log_2 n\right\rfloor + 1} - 1\),即兩種情況都能取到上界。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, ans[kN];
LL k;
//=============================================================
void check() {
  int temp = 0;
  for (int i = 1; i <= n; ++ i) {
    if (i % 2 == 0) temp |= ans[i];
    else temp &= ans[i];
  }
  std::cout << "---" << temp << "\n";
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    std::cin >> n;
    
    if (n & 1) {
      k = n;
      ans[n] = n;
      ans[n - 1] = n - 1;
      ans[n - 2] = 1;
      for (int i = 1; i <= n - 3; ++ i) ans[i] = i + 1;
    } else {
      k = (1ll << (((LL) log2(n)) + 1)) - 1l;
      std::map<int, bool> vis;
      std::vector<int> b[2];
      int len = n;

      ans[n] = n;
      ans[n - 1] = k ^ n;
      if ((k ^ n) == 1) {
        len = 2;
      } else {
        len = 4;
        ans[n - 2] = ans[n - 1] - 1;
        ans[n - 3] = 1;
      }
      for (int i = n - len + 1; i <= n; ++ i) vis[ans[i]] = 1;
      for (int i = 1; i <= n; ++ i) if (!vis[i]) b[i % 2].push_back(i);
      for (int i = 1, j = 0; i <= n - len; ++ i, j ^= 1) ans[i] = b[j].back(), b[j].pop_back();
    }
    // check();
    std::cout << k << "\n";
    for (int i = 1; i <= n; ++ i) std::cout << ans[i] << " ";
    std::cout << "\n";
  }
  return 0;
}

D 貪心,單調棧

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
const LL p = 1e9 + 7;
//=============================================================
int n;
LL cnt2[kN], a[kN], b[kN], pw2[kN];
int top, st[kN];
//=============================================================
LL qpow(LL x_, LL y_) {
  LL ret = 1;
  while (y_) {
    if (y_ & 1) ret = ret * x_ % p;
    x_ = x_ * x_ % p, y_ >>= 1ll;
  }
  return ret;
}
bool cmp(int p1_, int p2_) {
  if (pw2[p2_] > 30) return 1;
  return (1ll << pw2[p2_]) * b[p2_] >= b[p1_];
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    std::cin >> n;
    for (int i = 1; i <= n; ++ i) cnt2[i] = 0;
    for (int i = 1; i <= n; ++ i) std::cin >> a[i], b[i] = a[i];
    for (int i = 1; i <= n; ++ i) {
      while (b[i] % 2 == 0) ++ cnt2[i], b[i] /= 2;
    }
    
    top = 0;
    LL ans = 0;
    for (int i = 1; i <= n; ++ i) {
      ans += b[i];

      pw2[i] = cnt2[i];
      while (top && cmp(st[top], i)) {
        pw2[i] += pw2[st[top]];
        ans -= b[st[top]] * (qpow(2, pw2[st[top]]) - 1 + p) % p;
        ans = (ans + p) % p;

        pw2[st[top]] = 0;
        -- top;
      }
      st[++ top] = i;
      ans += b[i] * (qpow(2, pw2[i]) - 1 + p) % p;
      ans %= p;

      std::cout << ans << " ";
    }
    std::cout << "\n";
  }
  return 0;
}

E 結論,數論分塊

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const LL kInf = 1e18 + 2077;
//=============================================================
LL x, y, z, k, ans;
//=============================================================
void check(LL r_, LL c1_, LL d1_) {
  LL c2 = kInf;

  for (LL r = r_ * k + k, l; r > r_ * k; r = l - 1) {
    l = std::max(r_ * k + 1, (LL) ceil(1.0 * (z - d1_) / ceil(1.0 * (z - d1_) / r)));
    c2 = std::min(c2, x * (l - r_ * k) + y * ((LL) ceil(1.0 * (z - d1_) / l)));
  }

  ans = std::min(ans, c1_ + c2);
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    std::cin >> x >> y >> z >> k;
    
    ans = kInf;
    for (LL round = 0; ; ++ round) {
      LL c1 = round * (k * x + y);
      LL d1 = round * (round + 1ll) / 2ll * k;
      if (d1 >= z) {
        ans = std::min(ans, c1);
        break;
      }
      check(round, c1, d1);
    }
    std::cout << ans << "\n";
  }
  return 0;
}

寫在最後

怎麼一堆思維結論題+打表,把我這種沒腦子的呆瓜鯊了。

好想死掉。

相關文章