# CSP-S 2020 简要题解

## 题目链接

https://loj.ac/p?keyword=CSP-S%202020

## 题解

### A. 儒略日 / julian

#include<bits/stdc++.h>

using namespace std;

const int N = 123456;
const int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int n;
bool cont;

struct day_t {
int d, m, y;
bool bc;

day_t() {
}

day_t(int d, int m, int y, bool bc): d(d), m(m), y(y), bc(bc) {
}

void print() {
cout << d << ' ' << m << ' ' << y;
if (bc) {
cout << " BC";
}
cout << '\n';
}

int get_days(int m, int y, bool bc) {
if ((bc && y % 4 == 1) || (!bc && y % 4 == 0)) {
if (cont && !bc && (y % 4 || (y % 400 && y % 100 == 0))) {
return days[m];
} else {
return m == 2 ? 29 : days[m];
}
} else {
return days[m];
}
}

void next_day(int& d, int& m, int& y, bool& bc) {
++d;
if (d > get_days(m, y, bc)) {
d = 1;
if (++m == 13) {
m = 1;
if (bc) {
if (--y == 0) {
bc = false;
++y;
}
} else {
++y;
}
}
}
}

long long check(int x) {
long long result = (x - 1582) * 365ll;
result += (x - 1580) / 4;
result -= (x - 1500) / 100;
result += (x - 1200) / 400;
return result;
}

int main() {
freopen("julian.in", "r", stdin);
freopen("julian.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
vector<pair<long long, int>> q;
for (int i = 1; i <= n; ++i) {
long long x;
cin >> x;
q.emplace_back(x, i);
}
sort(q.begin(), q.end());
int p = 0, d = 1, m = 1, y = 4713, normal = 0;
bool bc = true;
while (1) {
while (p < n && q[p].first == normal) {
answer[q[p].second] = day_t(d, m, y, bc);
++p;
}
next_day(d, m, y, bc);
if (d == 5 && m == 10 && y == 1582 && !bc) {
break;
}
++normal;
}
cont = true;
while (p < n) {
int l = 1582, r = (int)1e9;
long long rest = q[p].first - normal - 1;
while (l != r) {
int mid = (l + r >> 1) + 1;
if (rest >= check(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
rest -= check(l);
int d = 15, m = 10, y = l;
bool bc = false;
while (rest--) {
next_day(d, m, y, bc);
}
answer[q[p].second] = day_t(d, m, y, bc);
++p;
}
for (int i = 1; i <= n; ++i) {
}
return 0;
}


### B. 动物园 / zoo

#include<bits/stdc++.h>

using namespace std;

int n, m, c, k;
bool exist[65];

int main() {
freopen("zoo.in", "r", stdin);
freopen("zoo.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m >> c >> k;
for (int i = 1; i <= n; ++i) {
unsigned long long x;
cin >> x;
for (int j = 0; j < k; ++j) {
if (x >> j & 1) {
exist[j] = true;
}
}
}
int kinds = k;
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
if (!exist[x]) {
exist[x] = true;
--kinds;
}
}
if (kinds == 64) {
if (!n) {
cout << "18446744073709551616" << '\n';
} else {
cout << 18446744073709551615ull - (n - 1) << '\n';
}
} else {
cout << (1ull << kinds) - n << '\n';
}
return 0;
}


### C. 函数调用 / call

#include<bits/stdc++.h>

using namespace std;

const int N = 123456;
const int mod = 998244353;

void add(int& x, int y) {
x += y;
if (x >= mod) {
x -= mod;
}
}

int mul(int x, int y) {
return (long long) x * y % mod;
}

int n, m, q, a[N], b[N], type[N], p[N], value[N], mult[N], fun[N];
bool visit[N];

void dfs(int x) {
visit[x] = true;
if (type[x] == 2) {
mult[x] = value[x];
} else {
mult[x] = 1;
for (auto y : adj[x]) {
if (!visit[y]) {
dfs(y);
}
mult[x] = mul(mult[x], mult[y]);
}
int foobar = 1;
for (auto y : adj[x]) {
foobar = mul(foobar, mult[y]);
}
}
}

void rdfs(int x) {
visit[x] = true;
for (auto e : radj[x]) {
int y = e.first;
if (!visit[y]) {
rdfs(y);
}
}
if (type[x] == 1) {
}
}

int main() {
freopen("call.in", "r", stdin);
freopen("call.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
cin >> m;
for (int i = 1; i <= m; ++i) {
cin >> type[i];
if (type[i] == 1) {
cin >> p[i] >> value[i];
} else if (type[i] == 2) {
cin >> value[i];
} else {
int k, x;
cin >> k;
while (k--) {
cin >> x;
}
}
}
cin >> q;
for (int i = 1; i <= q; ++i) {
cin >> fun[i];
}
++m;
for (int i = 1; i <= q; ++i) {
}
dfs(m);
int foobar = mult[m];
memset(visit, false, sizeof visit);
memset(mult, 0, sizeof mult);
mult[m] = 1;
for (int i = 1; i <= m; ++i) {
if (type[i] == 1) {
rdfs(i);
}
}
for (int i = 1; i <= n; ++i) {
cout << ((mul(a[i], foobar) + b[i]) % mod) << " \n"[i == n];
}
return 0;
}


### D. 贪吃蛇 / snakes

• 建立队列 $$Q_1, Q_2$$，初始时队列 $$Q_1$$ 里由首到尾按顺序存有单调不降的 $$n$$ 个数。每次将 $$Q_1$$$$Q_2$$ 队尾（首）的数中较大（小）的取出作为所有数中最大（小）的数，两者作差得到需要插入队列的新数 $$x$$，若 $$x$$ 不大于 $$Q_1$$ 中最小的数，则将 $$x$$ 插入到 $$Q_1$$ 的队首，否则将 $$x$$ 插入到 $$Q_2$$ 的队首。

#include<bits/stdc++.h>

using namespace std;

const int N = 1234567;

class my_array {
pair<int, int> a[N << 1];

public:
void reset() {
memset(a, 0, sizeof a);
}

pair<int, int>& operator [] (int x) {
return a[N + x];
}
} b;

int n, a[N], p[N], foobar[N];

int main() {
freopen("snakes.in", "r", stdin);
freopen("snakes.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
int tt;
cin >> tt >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
auto solve = [&] () {
int l = 1, r = n;
b.reset();
for (int i = 1; i <= n; ++i) {
b[i] = make_pair(a[i], i);
p[i] = n;
}
deque<pair<int, int>> q;
for (int i = 1; i < n; ++i) {
pair<int, int> out, eater;
if (l <= r) {
out = b[l];
eater = b[r];
++l;
--r;
if (q.size()) {
if (out > q.front()) {
--l;
out = q.front();
q.pop_front();
}
if (eater < q.back()) {
++r;
eater = q.back();
q.pop_back();
}
}
} else {
out = q.front();
eater = q.back();
q.pop_front();
q.pop_back();
}
foobar[i] = eater.second;
p[out.second] = i;
pair<int, int> new_snake = make_pair(eater.first - out.first, eater.second);
if (l > r || new_snake < b[l]) {
b[--l] = new_snake;
} else {
q.push_front(new_snake);
}
}
int ban = n, answer = 1;
for (int i = n - 1; i; --i) {
if (p[foobar[i]] < ban) {
answer = n - i + 1;
ban = i;
}
}
};
cout << solve() << '\n';
while (--tt) {
int k, x, y;
cin >> k;
for (int i = 1; i <= k; ++i) {
cin >> x >> y;
a[x] = y;
}
cout << solve() << '\n';
}
return 0;
}


posted @ 2021-08-13 20:45  ImagineC  阅读(338)  评论(0编辑  收藏  举报