「題解」Codeforces Round 895 (Div. 3)

A. Two Vessels

Problem

題目

Sol & Code

簽到題

#include <bits/stdc++.h>

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T, a, b, c;

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d %d %d", &a, &b, &c);
    double res = std::abs(b - a) / 2.0;
    printf("%d\n", (int)std::ceil(res / c));
  }
  return 0;
}

B. The Corridor or There and Back Again

Problem

題目

Sol & Code

對於每個陷阱(不考慮其他陷阱)求最多能平安到達的位置,最後對每個陷阱取最小值。

#include <bits/stdc++.h>
#define N 101

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T, n, a[N];

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    for (int i = 1, x, y; i <= n; ++i) {
      scanf("%d %d", &x, &y);
      a[i] = x + (int)std::floor((y - 1) / 2.0);
    }
    int ans = 114514;
    for (int i = n; i >= 1; --i) ans = min(ans, a[i]);
    printf("%d\n", ans);
  }
  return 0;
}

C. Non-coprime Split

Problem

題目

Sol & Code

考慮 \([l,r]\) 這個區間的長度。若長度爲 \(2\)\(l,r\) 一奇一偶,討論可知 \([1,2],[2,3]\) 無解,其他情況答案可爲將 \(l,r\) 中偶數分爲兩半。
若長度爲 \(3\),討論可知 \([1,3]\) 無解,有解的情況答案容易得出不再詳細說。長度大於 \(3\) 肯定有解,答案也容易得出。若長度爲 \(1\),考慮是 \(a+b =l\) 的情況,若 \(gcd(a,b) = 1\) 說明\(a,b\) 無公共質因數,可以根據算數基本定理可知不存在整除 \(l\) 且小於 \(l\) 的質數故 \(l\) 爲質數,有解的情況即 \(l\) 不爲質數,找個公共的質因子 \(p\),令 \(a = p,b = l - p\) 即可。

#include <bits/stdc++.h>
#define N 10000001

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

bool vis[N];
int T, l, r, cnt, pri[N];

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

void getprime() {
  for (int i = 2; i < N; ++i) {
    if (!vis[i]) pri[++cnt] = i;
    for (int j = 1; j <= cnt; ++j) {
      if (1ll * i * pri[j] >= N) break;
      vis[i * pri[j]] = true;
      if (i % pri[j] == 0) break;
    }
  }
}

int main() {
  scanf("%d", &T);
  getprime();
  while (T--) {
    scanf("%d %d", &l, &r);
    if (r - l + 1 == 3) {
      if (l == 1) puts("-1");
      else {
        if (l & 1) printf("%d %d\n", (l + 1) / 2, (l + 1) / 2);
        else printf("%d %d\n", (l + 2) / 2, (l + 2) / 2);
      }
    } else if (r - l + 1 == 2) {
      if (l == 1 || l == 2) puts("-1");
      else {
        if (l & 1) printf("%d %d\n", (l + 1) / 2, (l + 1) / 2);
        else printf("%d %d\n", l / 2, l / 2);
      }
    } else if (l == r) {
      if (l & 1) {
        if (vis[l]) {
          int prt = 0;
          for (int i = 1; i <= cnt; ++i) {
            if (l % pri[i] == 0) {
              if ((l / pri[i]) & 1) { prt = pri[i]; break; }
            }
          }
          if (!prt) puts("-1");
          else printf("%d %d\n", prt, l - prt);
        } else puts("-1");
      } else {
        if (l != 2) printf("%d %d\n", l / 2, l / 2);
        else puts("-1");
      }
    } else {
      if (r & 1) printf("%d %d\n", (r - 1) / 2, (r - 1) / 2);
      else printf("%d %d\n", r / 2, r / 2);
    }
  }
  return 0;
}

D. Plus Minus Permutation

Problem

題目

Sol & Code

根據題意可知 \(x\) 的貢獻有 \(\lfloor \dfrac{n}{x}\rfloor\) 個數記作 \(a\)\(y\) 的貢獻有 \(\lfloor \dfrac{n}{x}\rfloor\) 個數記作 \(b\),其中兩者共同的貢獻有 \(\lfloor \dfrac{n}{\lcm(x,y)}\rfloor\)(其中 \(\lcm(x,y)\)\(x,y\) 的最小公倍數)個數記作 \(c\)

所以答案爲 \(n + (n - 1) + \dots + [n - (a - c) + 1] - [1 + 2 + \dots + (b - c)]\)

#include <bits/stdc++.h>

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T;
ll n, x, y;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } 
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%lld %lld %lld", &n, &x, &y);
    ll num1 = n / x - n / lcm(x, y), num2 = n / y - n / lcm(x, y);
    printf("%lld\n", (n + n - num1 + 1) * num1 / 2 - (1 + num2) * num2 / 2);
  }
  return 0;
}

E. Data Structures Fan

Problem

題目

Sol & Code

線段樹可做

#include <bits/stdc++.h>
#define N 100001
#define lson now << 1
#define rson now << 1 | 1 

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

std::string s;
int T, n, q, w[N];
struct Node {
  int l, r, xor0, xor1, lazy;
}t[N << 2];

void build(int l, int r, int now) {
  t[now].l = l, t[now].r = r, t[now].xor0 = 0, t[now].xor1 = 0, t[now].lazy = 0;
  if (l == r) {
    if (s[l - 1] == '0') t[now].xor0 = w[l];
    else t[now].xor1 = w[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, lson), build(mid + 1, r, rson);
  t[now].xor0 = t[lson].xor0 ^ t[rson].xor0;
  t[now].xor1 = t[lson].xor1 ^ t[rson].xor1;
}

void pushdown(int now) {
  if (t[now].l == t[now].r) return;
  t[lson].lazy ^= 1, t[rson].lazy ^= 1;
  int tmp1 = t[lson].xor0, tmp2 = t[rson].xor0;
  t[lson].xor0 = t[lson].xor1, t[lson].xor1 = tmp1;
  t[rson].xor0 = t[rson].xor1, t[rson].xor1 = tmp2;
  t[now].lazy = 0;
}

void fix(int x, int y, int now) {
  if (t[now].l >= x && t[now].r <= y) {
    t[now].lazy ^= 1;
    int tmp = t[now].xor0;
    t[now].xor0 = t[now].xor1;
    t[now].xor1 = tmp;
    return ;
  }
  if (t[now].lazy) pushdown(now);
  int mid = (t[now].l + t[now].r) >> 1;
  if (x <= mid) fix(x, y, lson);
  if (y > mid) fix(x, y, rson);
  t[now].xor0 = t[lson].xor0 ^ t[rson].xor0;
  t[now].xor1 = t[lson].xor1 ^ t[rson].xor1;
}

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);
    std::cin >> s;
    build(1, n, 1);
    scanf("%d", &q);
    for (int i = 1, opt, x, y; i <= q; ++i) {
      scanf("%d %d", &opt, &x);
      if (opt == 1) {
        scanf("%d", &y);
        fix(x, y, 1);
      } else printf("%d ", x ? t[1].xor1 : t[1].xor0);
    }
    puts("");
  }
  return 0;
}

總結

C. 分類討論好像複雜了。

E. 現在是隻會暴力數據結構的 fw 了(甚至數據結構都不會),異或前綴和。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章