2019-2020 ICPC, Asia Jakarta Regional Contest
Contest Info
[Practice Link](https://codeforces.com/contest/1252)
Solved | A | B | C | D | E | F | G | H | I | J | K | L |
---|---|---|---|---|---|---|---|---|---|---|---|---|
7/12 | O | - | O | - | O | - | O | O | - | O | O | - |
- O 在比赛中通过
- Ø 赛后通过
- ! 尝试了但是失败了
- - 没有尝试
Solutions
A. Copying Homework
签到。
C. Even Path
题意:
给出一个\(n \cdot n\)的矩阵,再给出两个长度为\(n\)的序列\(b, c\),并且有\(a_{i, j} = b_i + c_j\),定义一条'Even Path'为一条经过的格子上面都是偶数的路径。
现在每次询问给出\(x_1, y_1, x_2, y_2\),询问\((x_1, y_1) \rightarrow (x_2, y_2)\)是否存在一条'Even Path'
思路:
发现路径的扩展每次都是扩展一行或者一列,那么当且仅当\(b[x_1] \cdots b[x_2]\)这一段数的奇偶性相同并且\(c[x_1] \cdots c[x_2]\)这一段数的奇偶性相同即可。
代码:
view code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, q, a[N], b[N], idA[N], idB[N];
int main() {
while (scanf("%d%d", &n, &q) != EOF) {
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
a[i] %= 2;
}
for (int i = 1; i <= n; ++i) {
scanf("%d", b + i);
b[i] %= 2;
}
idA[1] = 1;
idB[1] = 1;
for (int i = 2; i <= n; ++i) {
if (a[i] == a[i - 1]) {
idA[i] = idA[i - 1];
} else {
idA[i] = idA[i - 1] + 1;
}
if (b[i] == b[i - 1]) {
idB[i] = idB[i - 1];
} else {
idB[i] = idB[i - 1] + 1;
}
// cout << idA[i] << " " << idB[i] << endl;
}
int x[2], y[2];
while (q--) {
scanf("%d%d%d%d", x, y, x + 1, y + 1);
if (idA[x[0]] == idA[x[1]] && idB[y[0]] == idB[y[1]]) {
puts("YES");
} else {
puts("NO");
}
}
}
return 0;
}
E. Songwriter
题意:
给出一个序列\(a_i\),要求构造一个序列\(b_i\),满足\(b_i \in [L, R]\),并且\(b_i\)和\(b_{i + 1}\)的大小关系和\(a_i\)与\(a_{i + 1}\)相同
并且满足对于任意\(i \in [1, n - 1]\),都有\(|b_i - b_{i + 1}| \leq K\)。
输出满足要求的字典序最小的\(b_i\)
思路:
令\(l_n = L, r_n = R\),然后往前推出每个\(b_i\)的合法取值范围。
然后从前往后贪心即可。
代码:
view code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, L, R, K, a[N], l[N], r[N];
void gao() {
l[n] = L, r[n] = R;
for (int i = n - 1; i >= 1; --i) {
if (a[i] == a[i + 1]) {
l[i] = l[i + 1];
r[i] = r[i + 1];
} else if (a[i] < a[i + 1]) {
r[i] = r[i + 1] - 1;
l[i] = max(L, l[i + 1] - K);
} else if (a[i] > a[i + 1]) {
l[i] = l[i + 1] + 1;
r[i] = min(R, r[i + 1] + K);
}
if (l[i] > r[i]) {
puts("-1");
return;
}
}
int x = l[1];
for (int i = 1; i <= n; ++i) {
printf("%d%c", x, " \n"[i == n]);
if (i < n) {
if (a[i] < a[i + 1]) {
x = max(l[i + 1], x + 1);
} else if (a[i] > a[i + 1]) {
x = max(x - K, l[i + 1]);
}
}
}
}
int main() {
while (scanf("%d%d%d%d", &n, &L, &R, &K) != EOF) {
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
}
gao();
}
return 0;
}
G. Performance Review
代码:
view code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, q;
vector<vector<int> >G;
int a[N], rk[N], remind[N];
struct SEG {
struct node {
int Min;
int lazy;
node() {}
node(int _Min, int _lazy) {
Min = _Min;
lazy = _lazy;
}
void up(int x) {
Min += x;
lazy += x;
}
}t[N << 2];
void down(int id) {
int &lazy = t[id].lazy;
if (lazy) {
t[id << 1].up(lazy);
t[id << 1 | 1].up(lazy);
lazy = 0;
}
}
void pushup(int id) {
t[id].Min = min(t[id << 1].Min, t[id << 1 |1].Min);
}
void build(int id, int l, int r) {
t[id] = {0, 0};
if (l == r) {
t[id].Min = remind[l];
t[id].lazy = 0;
return ;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
pushup(id);
}
void modify(int id, int l, int r, int ql, int qr, int v) {
if (ql > qr) return ;
if (l >= ql && r <= qr) {
t[id].up(v);
return ;
}
int mid = (l + r) >> 1;
down(id);
if (ql <= mid) modify(id << 1, l, mid, ql, qr, v);
if (qr > mid) modify(id << 1 | 1, mid + 1, r, ql, qr, v);
pushup(id);
}
int query(int id, int l, int r, int ql, int qr) {
if (l >= ql && r <= qr) return t[id].Min;
int mid = (l + r);
down(id);
int res = INF;
if (ql <= mid) res = min(res, query(id << 1, l, mid, ql, qr));
if (qr > mid) res = min(res, query(id << 1 | 1, mid + 1, r, ql, qr));
return res;
}
}seg;
int main() {
while (scanf("%d %d %d", &n, &m, &q) != EOF) {
G.clear();
G.resize(m + 1);
rk[1] = 1;
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
if (a[i] > a[1]) {
rk[1]++;
}
}
for (int i = 1, r, b; i <= m; ++i) {
scanf("%d", &r);
rk[i + 1] = rk[i];
for (int j = 1; j <= r; ++j) {
scanf("%d", &b);
G[i].push_back(b);
if (b > a[1]) {
rk[i + 1]++;
}
}
remind[i] = n - r - rk[i];
}
seg.build(1, 1, m);
for (int _q = 1, x, y, z; _q <= q; ++_q) {
scanf("%d %d %d", &x, &y, &z);
int pre = G[x][y - 1], now = z;
if (pre < a[1] && now > a[1]) {
seg.modify(1, 1, m, x + 1, m, -1);
}
if (pre > a[1] && now < a[1]) {
seg.modify(1, 1, m, x + 1, m, 1);
}
int rank = seg.t[1].Min;
puts(rank < 0 ? "0" : "1");
G[x][y - 1] = z;
}
}
return 0;
}
H. Twin Buildings
题意:
给出\(n\)个地基,要造两个占地面积相同(长宽相同)的房子,问最大占地面积是多少。
可以建在两个地基上,也可以建在一个地基上
思路:
- 建在一个地基上:暴力枚举
- 建在两个地基上:容易发现,肯定有其中一个地基的一边被完整用上了,那么枚举这一边,然后在从所有最长边大于等于这个变成的地基中按另一边排序选最大和次大来建,这个用堆维护即可
代码:
view code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 10;
int n, ce;
struct E {
ll x, y; int id;
bool operator < (const E &other) const {
return x < other.x;
}
}e[N];
int main() {
while (scanf("%d", &n) != EOF) {
ce = 0;
for (int i = 1, x, y; i <= n; ++i) {
scanf("%d%d", &x, &y);
e[++ce] = {x, y, i};
e[++ce] = {y, x, i};
}
sort(e + 1, e + 1 + ce);
priority_queue <E> pq;
ll res = 0;
for (int i = ce; i >= 1; --i) {
res = max(res, e[i].x * e[i].y);
ll now = e[i].x;
pq.push({e[i].y, e[i].x, e[i].id});
while (pq.size() > 1) {
E t1 = pq.top(); pq.pop();
E t2 = pq.top(); pq.pop();
if (t1.id == t2.id) {
pq.push(t1);
} else {
pq.push(t1);
pq.push(t2);
break;
}
}
if (pq.size() > 1) {
E t1 = pq.top(); pq.pop();
E t2 = pq.top(); pq.pop();
res = max(res, now * t2.x * 2);
pq.push(t1);
pq.push(t2);
}
}
printf("%lld", res / 2);
puts((res % 2) ? ".5" : ".0");
}
return 0;
}
J. Tiling Terrace
题意:
给出一个字符串,里面只包含'.', '#':
- 如果拼成'.',那么会得到\(G_1\)的分数
- 如果拼成'..',那么会得到\(G_2\)的分数
- 如果拼成'.#.',那么会得到\(G_3\)的分数
现在要将该字符串分成若干段,每一段都是上述的某一个,使得分数最大,并且保证字符串中'#'的个数不超过\(50\)。
但是分段后,要满足第一种类型字符串不超过\(K\)个
思路:
考虑'..'可以换成两个'.',所以\(f[i][j]\)表示前\(i\)个字符,有\(j\)个第三种类型字符串的情况下,最多包含多少个第二类型字符串,然后枚举每种状态贪心即可。
代码:
view code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;
int n, limit, pre[N], g[3], f[N][60];
char s[N];
ll get(ll x, ll y) {
if (x >= limit || g[0] * 2 <= g[1]) {
x = min(x, 1ll * limit);
return x * g[0] + y * g[1];
}
if (limit - x >= y * 2) {
x += y * 2;
return x * g[0];
}
if ((limit - x) % 2 == 0) {
int need = limit - x;
y -= need / 2;
x += need;
return x * g[0] + y * g[1];
} else {
int need = limit - x - 1;
y -= need / 2;
x += need;
--y;
return x * g[0] + y * g[1] + max(g[0], g[1]);
}
}
int main() {
while (scanf("%d%d", &n, &limit) != EOF) {
memset(f, 0, sizeof f);
for (int i = 0; i < 3; ++i) scanf("%d", g + i);
scanf("%s", s + 1);
memset(f, -0x3f, sizeof f);
f[0][0] = 0;
pre[0] = 0;
for (int i = 1; i <= n; ++i) {
pre[i] = pre[i - 1] + (s[i] == '.');
for (int j = 0; j <= 50; ++j) {
f[i][j] = f[i - 1][j];
}
if (i > 1 && s[i] == '.' && s[i - 1] == '.') {
for (int j = 0; j <= 50; ++j) {
f[i][j] = max(f[i][j], f[i - 2][j] + 1);
}
}
if (i > 2 && s[i] == '.' && s[i - 1] == '#' && s[i - 2] == '.') {
for (int j = 0; j <= 50; ++j) {
f[i][j + 1] = max(f[i][j + 1], f[i - 3][j]);
}
}
}
ll res = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= 50 && f[i][j] >= 0; ++j) {
ll now = 1ll * j * g[2];
ll x = pre[i] - (j + f[i][j]) * 2;
ll y = f[i][j];
now += get(x, y);
res = max(res, now);
}
}
printf("%lld\n", res);
}
return 0;
}
K. Addition Robot
线段树维护矩阵乘法。
代码:
view code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, q; char s[N];
struct Matrix {
int a[2][2];
void init() { a[0][0] = a[1][1] = 1; a[0][1] = a[1][0] = 0; }
int* operator[] (int x) { return a[x]; }
Matrix operator * (Matrix b) {
Matrix res;
res[0][0] = (1ll * a[0][0] * b[0][0] % mod + 1ll * a[0][1] * b[1][0] % mod) % mod;
res[0][1] = (1ll * a[0][0] * b[0][1] % mod + 1ll * a[0][1] * b[1][1] % mod) % mod;
res[1][0] = (1ll * a[1][0] * b[0][0] % mod + 1ll * a[1][1] * b[1][0] % mod) % mod;
res[1][1] = (1ll * a[1][0] * b[0][1] % mod + 1ll * a[1][1] * b[1][1] % mod) % mod;
return res;
}
}A, B, res;
struct SEG {
struct node {
Matrix a[2];
int lazy;
void init() {
a[0].init(); a[1].init();
lazy = 0;
}
void up() {
swap(a[0], a[1]);
lazy ^= 1;
}
}t[N << 2];
void pushup(int id) {
t[id].a[0] = t[id << 1 | 1].a[0] * t[id << 1].a[0];
t[id].a[1] = t[id << 1 | 1].a[1] * t[id << 1].a[1];
}
void down(int id) {
int &lazy = t[id].lazy;
if (lazy) {
t[id << 1].up();
t[id << 1 | 1].up();
lazy = 0;
}
}
void build(int id, int l, int r) {
if (l == r) {
t[id].a[0] = A;
t[id].a[1] = B;
if (s[l] == 'B') {
swap(t[id].a[0], t[id].a[1]);
}
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
pushup(id);
}
void modify(int id, int l, int r, int ql, int qr) {
if (l >= ql && r <= qr) {
t[id].up();
return;
}
int mid = (l + r) >> 1;
down(id);
if (ql <= mid) modify(id << 1, l, mid, ql, qr);
if (qr > mid) modify(id << 1 | 1, mid + 1, r, ql, qr);
pushup(id);
}
Matrix query(int id, int l, int r, int ql, int qr) {
if (l >= ql && r <= qr) return t[id].a[0];
int mid = (l + r) >> 1;
down(id);
Matrix res; res.init();
if (qr > mid) res = res * query(id << 1 | 1, mid + 1, r, ql, qr);
if (ql <= mid) res = res * query(id << 1, l, mid, ql, qr);
return res;
}
}seg;
int main() {
A = {1, 1, 0, 1};
B = {1, 0, 1, 1};
while (scanf("%d%d", &n, &q) != EOF) {
scanf("%s", s + 1);
seg.build(1, 1, n);
int op, l, r, a, b;
for (int i = 1; i <= q; ++i) {
scanf("%d%d%d", &op, &l, &r);
if (op == 1) {
seg.modify(1, 1, n, l, r);
} else {
scanf("%d%d", &a, &b);
res = {a, 0, b, 0};
res = seg.query(1, 1, n, l, r) * res;
printf("%d %d\n", res[0][0], res[1][0]);
}
}
}
return 0;
}
2019-2020 ICPC, Asia Jakarta Regional Contest的更多相关文章
- 2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)
2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred) easy: ACE ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings
As you might already know, space has always been a problem in ICPC Jakarta. To cope with this, ICPC ...
- 2018 ICPC Asia Jakarta Regional Contest
题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . Ø Ø Ø Ø . Ο Ο:当场 Ø:已补 . : 待补 A. Edit Distance Thin ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path
Pathfinding is a task of finding a route between two points. It often appears in many problems. For ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest A. Copying Homework
Danang and Darto are classmates. They are given homework to create a permutation of N integers from ...
- 模拟赛小结:2019-2020 ICPC, Asia Jakarta Regional Contest
比赛链接:传送门 离金最近的一次?,lh大佬carry场. Problem A. Copying Homework 00:17(+) Solved by Dancepted 签到,读题有点慢了.而且配 ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path(思维)
Pathfinding is a task of finding a route between two points. It often appears in many problems. For ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest A. Copying Homework (思维)
Danang and Darto are classmates. They are given homework to create a permutation of N integers from ...
- Asia Jakarta Regional Contest 2019 I - Mission Possible
cf的地址 因为校强, "咕咕十段"队获得了EC-final的参赛资格 因为我弱, "咕咕十段"队现在银面很大 于是咕咕十段决定进行训练. 周末vp了一场, 这 ...
随机推荐
- Android—网络请求
import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; ...
- Springboot模板(thymeleaf、freemarker模板)
目的: 1.thymeleaf模板 2.Freemarker模板 thymeleaf模板 thymeleaf 的优点: 支持html5标准,页面无须部署到servlet开发到服务器上,直接通过浏览器就 ...
- Arm-Linux 移植 alsa
ref : https://www.cnblogs.com/yutingliuyl/p/6718875.html https://blog.csdn.net/yuanxinfei920/article ...
- 转 使用IParameterInspector, IOperationBehavior,Attribute(参数检查器、操作行为接口和标签)扩展WCF操作行为
public class EntryIdInspector : IParameterInspector { public int intParamIndex { get; set; } string ...
- springboot笔记04——读取配置文件+使用slf4j日志
前言 springboot常用的配置文件有yml和properties两种,当然有必要的时候也可以用xml.我个人更加喜欢用yml,所以我在这里使用yml作为例子.yml或properties配置文件 ...
- 炫酷的可视化工具包——cufflinks
前言 学过Python数据分析的朋友都知道,在可视化的工具中,有很多优秀的三方库,比如matplotlib,seaborn,plotly,Boken,pyecharts等等.这些可视化库都有自己的特点 ...
- 关于Vue中,父组件获取子组件的数据(子组件调用父组件函数)的方法
1. 父组件调用子组件时,在调用处传给子组件一个方法 :on-update="updateData" 2. 子组件在props中,接收这个方法并声明 props: { onUp ...
- axios拦截登陆过期请求多次
request.interceptors.response.use( response => { console.log(response.data.code) // console.log(r ...
- angular2-cli 环境搭建
开发工具:windows ,Vscode, npm, 前提:安装nodejs nodejs 模块全局安装路径配置:http://www.cnblogs.com/rancho-blog/p/656792 ...
- lumen生成key
在Lumen控制台运行php artisan key:generate提示: $ php artisan key:generate [Symfony\Component\Console\Excepti ...