本文同步发表在 YangTY’s Blog

ARC120A - Max Add

需要想一两分钟的贪心

ARC120B - Uniformly Distributed

Description

给定 H×WH \times WH×W 的方格,其中一些涂了红色,一些涂了蓝色,一些什么都没涂。问对于剩余的格子,有多少种涂色的方案使得从 (1,1)(1,1)(1,1) 到 (H,W)(H,W)(H,W) 上的所有路径经过的红格子数量都相等。

Solution

不难发现,对于一个从右上到左下的副对角线,其要么全为红色,要么全为蓝色。大体的理由如下:(非严格证明)

从 (1,1)(1,1)(1,1) 到 (H,W)(H,W)(H,W) 一定是会经过 H+W−1H + W - 1H+W−1 条如上面这样的副对角线的,所以我们一定要保证无论怎么穿过一条副对角线,其经过的红格子数量都是相同的。

所以直接做就行了,对于一条有红格子的副对角线,其对答案的贡献是 111;对于一条全空的副对角线,其对答案的贡献为 222(两种涂色方案);对于既有蓝色又有红色的副对角线,其对答案的贡献为 000。把这些贡献用乘法原理合并即可。

#include <cstdio>
#include <cstring>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define DEC(i, a, b) for (int i = a; i >= b; --i)typedef long long ll;const int maxn = 505;
const ll mod = 998244353;int h, w;
char s[maxn][maxn];
int r[maxn << 1], b[maxn << 1];int main()
{scanf("%d %d", &h, &w);FOR(i, 1, h) scanf("%s", s[i] + 1);ll ans = 1;FOR(i, 1, h)FOR(j, 1, w)if (s[i][j] == 'R')  ++r[i + j];else if (s[i][j] == 'B') ++b[i + j];FOR(i, 2, h + w)if (r[i] && !b[i]) ans *= 1ll;else if (b[i] && !r[i]) ans *= 1ll;else if (!b[i] && !r[i]) ans = ans * 2ll % mod;else ans = 0;printf("%lld\n", ans);return 0;
}

ARC120C - Swaps 2

Description

给定两个长度为 NNN 的序列 AAA 和 BBB。问对 AAA 进行有限次如下操作后能否使 AAA 变成 BBB:

  • 选择一个正整数 iii 使得 1≤i<N1\le i\lt N1≤i<N

    • 交换 AiA_iAi​ 和 Ai+1A_{i+ 1}Ai+1​ 的值
    • 使 AiA_iAi​ 加一
    • 使 Ai+1A_{i + 1}Ai+1​ 减一

如果能,问最少操作步数。

Solution

先考虑解的存在性。

我们观察一个数移动的情况:显然是往右走就减小,往左走就增大。设 AiA_iAi​ 的新位置为 DiD_iDi​,则必然有:
BDi=Ai+i−DiB_{D_i} = A_i + i - D_i BDi​​=Ai​+i−Di​
移项,
BDi+Di=Ai+iB_{D_i} + D_i = A_i + i BDi​​+Di​=Ai​+i
发现两边的形式很像,所以我们只需要建立两个新序列 {Ai+i}\{A_i + i\}{Ai​+i} 和 {Bi+i}\{B_i + i\}{Bi​+i} 然后将其值排序判断其能不能一一对应就可以判断有没有解了。

然后考虑解的最优性。

刚才的排序中,若按照值为第一关键字排序,原下标为第二关键字排序,则我们不难证明,此时一一对应的结果是最优的。这样子 DiD_iDi​ 就找到了。

然后我们把 AiA_iAi​ 移到 ADiA_{D_i}ADi​​ 的过程很像冒泡排序,用线段树维护一下 AAA 中元素的下标就可以做了。

#include <cstdio>
#include <cctype>
#include <algorithm>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define DEC(i, a, b) for (int i = a; i >= b; --i)
#define int long longconst int maxn = 2e5 + 5;int read()
{int s = 0, x = 0;char c = getchar();while (!isdigit(c))x |= (c == '-'), c = getchar();while (isdigit(c))s = s * 10 + c - '0', c = getchar();return x ? -s : s;
}struct node
{int val, id;bool operator<(const node &b)const{return val == b.val ? id < b.id : val < b.val;}
} ai[maxn], bi[maxn];int a[maxn], b[maxn], n;inline int myabs(int x)
{return x >= 0 ? x : -x;
}int f[maxn << 2], tag[maxn << 1], d[maxn];#define L (k << 1)
#define R (L | 1)
#define M ((i + j) >> 1)void build(int i, int j, int k)
{if (i == j)return void(f[k] = i);build(i, M, L);build(M + 1, j, R);f[k] = f[L] + f[R];return;
}void pushdown(int i, int j, int k)
{tag[L] += tag[k], tag[R] += tag[k];f[L] += (M - i + 1) * tag[k];f[R] += (j - M) * tag[k];tag[k] = 0;return;
}void modify(int i, int j, int k, int x, int y, int d)
{if (x > y) return;if (i >= x && j <= y){f[k] += d * (j - i + 1);tag[k] += d;return;}pushdown(i, j, k);if (x <= M) modify(i, M, L, x, y, d);if (y > M) modify(M + 1, j, R, x, y, d);f[k] = f[L] + f[R];return;
}int query(int i, int j, int k, int x)
{if (i == j) return f[k];pushdown(i, j, k);if (x <= M) return query(i, M, L, x);else return query(M + 1, j, R, x);
}signed main()
{n = read();FOR(i, 1, n) a[i] = read(), ai[i].val = a[i] + i, ai[i].id = i;FOR(i, 1, n) b[i] = read(), bi[i].val = b[i] + i, bi[i].id = i;std::sort(ai + 1, ai + n + 1);std::sort(bi + 1, bi + n + 1);FOR(i, 1, n)if (ai[i].val != bi[i].val) return printf("-1\n"), 0;else d[bi[i].id] = ai[i].id;build(1, n, 1);int ans = 0;FOR(i, 1, n){ans += abs(query(1, n, 1, d[i]) - i);modify(1, n, 1, 1, d[i], 1);}printf("%lld\n", ans);return 0;
}

ARC120D - Bracket Score 2

Description

给定一个长度为 2N2N2N 的整数序列 AiA_iAi​,依照其构造一个长度为 2N2N2N 的合法括号序列,使得其分数最大,分数的计算方式:

  • 对于每一对匹配的括号 SiS_iSi​ 和 SjS_jSj​,其贡献为 ∣Aj−Ai∣|A_j - A_i|∣Aj​−Ai​∣
  • 将每一对匹配的括号的分数加起来得到总分

Solution

眼前一亮的构造。

不难发现,让大的尽量大,小的尽量小就可以使得总分最大。因此选出最大的 NNN 个 AiA_iAi​,标记为黑色,剩余的标记为白色。然后根据一黑一白配对的原则直接构造括号序列即可。

#include <cstdio>
#include <cctype>
#include <algorithm>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define DEC(i, a, b) for (int i = a; i >= b; --i)const int maxn = 4e5 + 5;int read()
{int s = 0, x = 0;char c = getchar();while (!isdigit(c))x |= (c == '-'), c = getchar();while (isdigit(c))s = s * 10 + c - '0', c = getchar();return x ? -s : s;
}int n, color[maxn], stk[maxn], top;struct node
{int v, i;bool operator<(const node &b) const {return v < b.v;}
} a[maxn];int main()
{n = read() << 1;FOR(i, 1, n) a[i].v = read(), a[i].i = i;std::sort(a + 1, a + n + 1);FOR(i, 1, n >> 1) color[a[i].i] = 1;FOR(i, 1, n){if (top && color[stk[top]] != color[i]) --top, putchar(')');else stk[++top] = i, putchar('(');}return 0;
}

AtCoder Regular Contest 120 解题报告相关推荐

  1. AtCoder Regular Contest 120 C - Swaps 2 线段树模拟

    传送门 文章目录 题意: 思路: 题意: 给你两个序列a,ba,ba,b,每次可以执行一个操作:将a[i]a[i]a[i]与a[i+1]a[i+1]a[i+1]交换,且让交换后的a[i]+1,a[i+ ...

  2. Atcoder Beginner Contest 124 解题报告

    心态爆炸.本来能全做出来的.但是由于双开了Comet oj一个比赛,写了ABC就去搞那个的B题 还被搞死了. 回来写了一会D就过了.可惜比赛已经结束了.真的是作死. A - Buttons #incl ...

  3. AtCoder Beginner Contest 132 解题报告

    前四题都好水.后面两道题好难. C Divide the Problems #include <cstdio> #include <algorithm> using names ...

  4. AtCoder Beginner Contest 285解题报告

    A - Edge Checker 2 Problem Statement Determine if there is a segment that directly connects the poin ...

  5. AtCoder题解——AtCoder Regular Contest 107——B - Quadruple

    题目相关 题目链接 AtCoder Regular Contest 107 B 题,https://atcoder.jp/contests/arc107/tasks/arc107_b. Problem ...

  6. AtCoder Regular Contest 065

    AtCoder Regular Contest 065 C - Daydream Score : 300300300 points 倒着来就行了,正着来会产生歧义匹配,dreamer,dreamdre ...

  7. AtCoder Regular Contest 100 D - Equal Cut 思维 + 前缀和

    传送门 文章目录 题意: 思路: 题意: 给你一个数组aaa,你要将其分成四份,让这四份中和的最大值−-−最小值最小,输出这个最小值. n≤2e5,ai≤1e9n\le2e5,a_i\le1e9n≤2 ...

  8. AtCoder Regular Contest 100 E - Or Plus Max Sos dp

    传送门 文章目录 题意: 思路: 题意: 给你一个长度为2n2^n2n的数组,让你对于所有的1≤k≤2n−11\le k\le 2^n-11≤k≤2n−1求最大的ai+aj,0≤i<j≤2n−1 ...

  9. AtCoder Regular Contest 061 E - Snuke‘s Subway Trip(建图 + dijkstra最短路 / 0/1bfs / 并查集)

    AtCoder Regular Contest 061 E - Snuke's Subway Trip problem 洛谷翻译 my idea 最近一直在做网络流,所以一读这题后,我就想到了最小费用 ...

  10. NOMURA Programming Contest 2021(AtCoder Regular Contest 121)

    文章目录 A - 2nd Greatest Distance B - RGB Matching C - Odd Even Sort D - 1 or 2 E - Directed Tree F - L ...

最新文章

  1. XJTLU Outstanding Student for 2017-2018!
  2. python 等值线 标注 间距、控制_python - Matplotlib-Contourf-如何使刻度线间距不均匀? - 堆栈内存溢出...
  3. project项目管理案例_做总助,哪能不懂项目管理!
  4. 奉献给你:《Visual C# 2005程序开发与界面设计秘诀》
  5. Android Ac 控件,Android控件--MultiAutoCompleteTextView
  6. 封装一个邮件发送工具类,一个字,巴适
  7. php判断手机浏览器,php 获取 手机浏览器的信息 | 学步园
  8. DevSecOps 现状:云 IT 的复杂度制造了“无法改变的”安全问题
  9. (转)你确定你的交易系统最快?
  10. 菜刀之中国蚁剑-安装使用及下载地址
  11. BadBoy下载安装
  12. Niubility!华为天才少年自制机械臂能给葡萄缝针
  13. 北风网-Spark视频从入门到精通(高级特性、案例实战、内核源码、性能调优)-中华石杉老师
  14. 关于矩阵相乘顺序的理解(跟旋转没关)
  15. 网站备案后服务器更换到家里,域名备案后能更换服务器吗
  16. 泰坦尼克号生存预测python_用Python预测泰坦尼克号生存情况
  17. 【软件测试面试题】证券项目面试过程总结
  18. LeetCode 860[Python]. 柠檬水找零 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
  19. 中小学数学卷子自动生成程序
  20. 让机器人懂感情:表情符与深度学习

热门文章

  1. 新浪微博相册批量下载工具V7.3
  2. CERT_HAS_EXPIRED
  3. 美国计算机编程竞赛,USACO美国计算机竞赛
  4. 关于MOSFET驱动电阻的选择
  5. Adobe reader update 无法将数值disableexceptionchainvaliddation写入键/sofeware...请验证您对该有足够
  6. beamer制作学术slide
  7. 天池-小布助手对话短文本语义匹配 复赛rank3、决赛rank4代码及解决方案
  8. 24个最新创意进度条设计,分分钟让你灵感爆表!!!
  9. c语言数组文曲星猜数游戏编程,第7章 数组-8数组的其他应用——文曲星猜数游戏.pdf...
  10. python加载模型包_R中的错误:需要h5py Python包来保存和加载模型