补题链接:Here

A - Plural Form

字符串,末尾有 s 的加es,不然加 s .

B - Go to Jail

输入的时候判断一下是否连续相等即可

C - A x B + C (math,欧拉筛)

题意:请问能找到多少组 (A,B,C)= N .

思路一:对于使得 \(A\times B < N\) 的(A,B) 都会存在唯一值 C 所以我们只需要对 (A,B) 计数即可

当 \(A\) 值确定时,\(B\) 为 \(⌊\frac{N -1}{A}⌋\) 。所以我们遍历 \(1\) ~ \(N - 1\) 即可。

AC 代码

int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int n;
cin >> n;
ll cnt = 0;
for (int i = 1; i <= n; ++i) cnt += (n - 1) / i;
cout << cnt << "\n";
return 0;
}

思路二:

另外在 CP wiki上也解释了这道题可以计算 \(N - C\) 的因子数来解决

固定 \(C\),符合条件的二元组 \((A,B)\) 的数目就等于 \(N−C\) 的因子数,而一个正整数的因子数可以通过质因数分解求得。

设:\(n = p_1^{a1}p_2^{a2}...p_n^{an}\),则其因子数为 \(∏_{i = 1}^n(a_i + 1)\)

所以我们就计算 \(1\dots N-1\) 每个数的因子数,然后求和即可。

因为\([1,x]\)范围内的质数个数近似为 \(\frac{x}{\ln x}\),总时间复杂度为 \(O(\frac{N\sqrt{N}}{\log N})\)。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using namespace std;
int main() {
int n;
cin >> n;
vector<int> primes = {2, 3, 5, 7, 11, 13};
for (int i = 17; i <= n - 1; i += 2) {
bool is_prime = true;
for (int j = 0; primes[j] * primes[j] <= i; ++j) {
if (i % primes[j] == 0) {
is_prime = false;
break;
}
}
if (is_prime)
primes.emplace_back(i);
}
int ans = 0;
for (int i = 1; i < n; ++i) {
int k = i;
int fac = 1;
for (int j = 0; primes[j] * primes[j] <= k; ++j) {
if (k % primes[j] == 0) {
int cnt = 0;
while (k % primes[j] == 0)
cnt++, k /= primes[j];
fac *= (cnt + 1);
}
}
if (k != 1) fac *= 2;
ans += fac;
}
cout << ans;
}

思路三:

欧拉筛,令f[i]为a*b=i的方案数,
f[i]的前缀和就是a*b<=i的方案数. 又因为题目中a*b+c的c必须>=1,那么我们输出f[n-1]即可,原理是留了一个1给c.

AC 代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn = 2e6 + 7;
ll f[maxn], n;
signed main() {
ios_base::sync_with_stdio(false), cin.tie(0);
for (int i = 1; i < maxn; ++i)
for (int j = i; j < maxn; j += i) f[j] += 1;
for (int i = 1; i < maxn; ++i) f[i] += f[i - 1];
cin >> n;
cout << f[n - 1] << "\n";
return 0;
}

D - Leaping Tak

题意:

给 \(N\) 个房间排成一行,房间编号为 \(1,2,...,N\)。目前高桥所在房间为 \(1\) ,现在他想移动到 \(N\) 号房间。

给定 \(K\) 个不相交的区间,而集合 \(S\) 是这 \(K\) 个区间的并集。移动规则如下:

  • 高桥在房间 \(i\),可以从集合 \(S\) 中选择一个整数 \(d\),这样可以移动到房间 \(i+d\)。
  • 高桥不可以移动到房间以外。

思路:

考虑我们当前处于 \(x\) 位置,我们上一步可能来自哪里?

我们需要检查所有的区间,然后找出对应的区间 \([l,r]\)(如果这样的区间存在的话),这一区间包含了所有能够利用原区间中的步长跳跃到当前位置的位置,也即上一步可能的位置。接下来我们将 \(sum(l,r)\)累加到 \(dp[x]\)上。

因为我们需要快速计算 \(sum(l,r)\),所以实际上我们可以使用前缀和 \(sum[i]\),而非 \(dp[i]\)。

  • \(\mathcal{O}(NK)\)
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const ll mod = 998244353;
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int n, k;
cin >> n >> k;
vector<pair<int, int>> v(k);
for (int i = 0; i < k; ++i) cin >> v[i].first >> v[i].second;
vector<ll> sum(n + 1, 0);
sum[1] = 1;
for (int i = 2; i <= n; ++i) {
ll cur = 0;
for (int j = 0; j < k; ++j) {
// 如果这个区间的起点大于 i 就不可能 i 是由这个点移动到的了
if (v[j].first >= i) continue;
int l = max(1, i - v[j].second);
int r = i - v[j].first;
cur += sum[r] - sum[l - 1];
}
cur %= mod;
sum[i] = (sum[i - 1] + cur + mod) % mod;
}
cout << (sum[n] - sum[n - 1] + mod) % mod;
return 0;
}

E - Sequence Sum

显然,操作足够多次后,一定会开始循环。因为 \(M\leq10^5\),所以循环的长度不超过 \(10^5\),因此我们直接模拟找出循环节即可。

注意:循环节不一定是 x 为起点

  • \(\mathcal{O}(M)\)
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
ll n, x, m;
cin >> n >> x >> m;
map<ll, ll> mp;
int idx = 0;
vector<ll> path;
do {
mp[x] = idx++;
path.emplace_back(x);
x = x * x % m;
} while (!mp.count(x));
int start = mp[x];
int len = idx - start;
ll sum = 0;
// 循环节之和
for (int i = start; i < idx; ++i) sum += path[i];
ll ans = 0;
if (n < start) // 可能未进入循环节就结束累加了
for (int i = 0; i < n; ++i) ans += path[i];
else {
for (int i = 0; i < start; ++i) ans += path[i];
ll loop = (n - start) / len;
ans += loop * sum;
ll res = (n - start) % len; // 多余一节
for (int i = 0; i < res; ++i) ans += path[start + i];
}
cout << ans << "\n";
return 0;
}

F - Simplified Reversi

当我们放一个白石头的时候,会改变多少黑石头的颜色?

对于第一种操作,这是由该列最上面的白石头决定的;对于第二种操作,这是由该行最左边的白石头决定的。

而每种操作的影响是什么呢?第一种操作会影响 \(1\dots X\) 行( \(X\) 是操作的列最上面的白石头所在的行),而第二种操作会影响 \(1\dots X\)列(\(X\)是操作的行最左边的白石头所在的列)。

很自然地想到用线段树来处理。一个储存每行最上面的白石头,另一个储存每列最左边的白石头。对于非叶结点,我们存储区间的最大值。因为我们每次操作相当于一个切割,把所有大于XX的数都变为XX,因此,存储区间最大值,可以让我们很方便地判断当前的切割是否产生了影响。

  • \(\mathcal{O}(QlogN)\).
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
#define MAXN 200005
#define lson (idx << 1)
#define rson (idx << 1 | 1) using namespace std;
typedef long long ll; struct Node {
int l, r, hi, lazy = 0;
}; struct SegTree {
Node s[MAXN << 2];
void calc(int idx) { s[idx].hi = max(s[lson].hi, s[rson].hi); } void pushdown(int idx) {
if (s[idx].lazy) {
for (int i = lson; i <= rson; ++i) {
if (s[i].hi > s[idx].lazy) {
s[i].hi = s[idx].lazy;
s[i].lazy = s[idx].lazy;
}
}
}
s[idx].lazy = 0;
} void build(int idx, int l, int r, vector<int> &a) {
s[idx].l = l, s[idx].r = r;
if (l == r) {
s[idx].hi = a[l];
return;
}
int mid = (l + r) >> 1;
build(lson, l, mid, a);
build(rson, mid + 1, r, a);
calc(idx);
} void update(int idx, int l, int r, int x) {
if (s[idx].hi <= x)
return;
if (s[idx].l >= l && s[idx].r <= r) {
s[idx].hi = x;
s[idx].lazy = x;
return;
}
pushdown(idx);
int mid = (s[idx].l + s[idx].r) >> 1;
if (l <= mid)
update(lson, l, r, x);
if (mid + 1 <= r)
update(rson, l, r, x);
calc(idx);
} int query(int idx, int l, int r) {
if (s[idx].l >= l && s[idx].r <= r)
return s[idx].hi;
pushdown(idx);
int ans = 0;
int mid = (s[idx].l + s[idx].r) >> 1;
if (l <= mid)
ans = max(ans, query(lson, l, r));
if (mid + 1 <= r)
ans = max(ans, query(rson, l, r));
return ans;
}
}; int main() {
int n, q;
cin >> n >> q;
vector<int> col(n + 1, n), row(n + 1, n);
col[n] = 1, row[n] = 1;
SegTree C, R;
C.build(1, 1, n, col);
R.build(1, 1, n, row);
ll ans = (ll)(n - 2) * (n - 2);
for (int i = 0; i < q; ++i) {
int t, x;
cin >> t >> x;
if (t == 1) {
int hi = C.query(1, x, x);
ans -= hi - 2;
R.update(1, 1, hi, x);
C.update(1, x, x, 1);
} else {
int hi = R.query(1, x, x);
ans -= hi - 2;
C.update(1, 1, hi, x);
R.update(1, x, x, 1);
}
}
cout << ans;
}

AtCoder Beginner Contest 179 个人题解(C欧拉筛,D前缀和,E循环节,F线段树)的更多相关文章

  1. KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解

    KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...

  2. AtCoder Beginner Contest 179

    比赛链接:https://atcoder.jp/contests/abc179/tasks A - Plural Form 题意 给出一个由小写字母组成的单词,如果单词以 $s$ 结尾,在单词的末尾加 ...

  3. AtCoder Beginner Contest 179 E - Sequence Sum (模拟)

    题意:\(f(x,m)\)表示\(x\ mod\ m\),\(A_{1}=1\),而\(A_{n+1}=f(A^{2}_{n},M)\),求\(\sum^{n}_{i=1}A_{i}\). 题解:多算 ...

  4. AtCoder Beginner Contest 089完整题解

    A - Grouping 2 Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement There a ...

  5. AtCoder Beginner Contest 179 D - Leaping Tak (DP)

    题意:给你一个数字\(n\)和\(k\)个区间,\(S\)表示所有区间的并的集合,你目前在\(1\),每次可以从集合中选择一个数字向右移动,问有多少种方法从\(1\)走到\(n\). 题解:我们从1开 ...

  6. 2018.09.08 AtCoder Beginner Contest 109简要题解

    比赛传送门 水题大赛? 全是水题啊!!! T1 ABC333 就是判断是不是两个数都是奇数就行了. 代码: #include<bits/stdc++.h> using namespace ...

  7. Atcoder Beginner Contest 138 简要题解

    D - Ki 题意:给一棵有根树,节点1为根,有$Q$次操作,每次操作将一个节点及其子树的所有节点的权值加上一个值,问最后每个节点的权值. 思路:dfs序再差分一下就行了. #include < ...

  8. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  9. AtCoder Beginner Contest 153 题解

    目录 AtCoder Beginner Contest 153 题解 A - Serval vs Monster 题意 做法 程序 B - Common Raccoon vs Monster 题意 做 ...

  10. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

随机推荐

  1. 【Javaweb】implements Serializable是什么意思?反序列化是什么意思?

    为了保证数据传输的可靠 性,常常要implements Serializable,为什么? 对象本质上是虚无缥缈的,只是内存中的一个地址,如果想要让对象持久化,让对象在网络上传输,总不可能传送一个内存 ...

  2. 在TCP四次挥手中,为什么客户端发送FIN后,还可以发送报文

    在TCP四次挥手中,为什么客户端发送FIN后,还可以发送报文 首先回顾下四次挥手的过程. 第一次挥手:客户端停止发送数据,主动关闭 TCP 连接,处于FIN_WAIT1状态,等待服务端确认. 第二次挥 ...

  3. Snipaste安装与使用教程

    一.下载 1.官网 下载地址 2.下载 可以直接在官网下载,也可以跳转微软仓库下载增强版的.如果是其他系统,mac在最下面,而Linux现在没有需要等待. 二.开始安装 1.下载完毕,是一压缩包绿色版 ...

  4. RAM 低功耗

    常见的ram低功耗方法包括的shutdown信号,1 关闭,0不关闭正常功能. ls低睡眠,深度睡眠. 关闭时节省90%功耗,数据丢失. 重新启动需要50ns以上. ram clk +gate

  5. 用pycharm创建一个django框架

    用pycharm创建一个django框架 注意解释器的选择和文件路径 创建完django项目 1.自动创建了一个templates目录(先删除) 2.把settings里的 TEMPLATES = [ ...

  6. NVIDIA RTX4090,你能用它做什么?

    都说男生是世界上最简单的动物,为什么呢?举个例子,你要给女朋友送礼,你可以选择包.口红.护肤品.化妆品等,而包的品牌和样式.口红的色号等足以让你挑得眼花缭乱.而男生不一样,如果女生选择给男生送礼,我相 ...

  7. Go语言实现GoF设计模式:适配器模式

    本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:适配器模式>,作者:元闰子. 简介 适配器模式(Adapter)是最常用的结构型模式之一,在现实生活中,适配器模式也是处处可见 ...

  8. [ARC169E] Avoid Boring Matches

    题解链接 非常厉害的一道题. 考虑无解是什么情况? R 的个数超过 \(2^{n-1}\) 先考虑如何判定.从前往后考虑,如果遇到一个 B,那么如果后面有 R,就选最靠前的 R,否则选最靠后的一个 B ...

  9. ROW_NUMBER 开窗函数优化方案(Oracle && PostgreSQL 性能比对)

    帮朋友优化一条很简单的窗口函数 ROW_NUMBER() OVER() , Oracle 迁移 PostgreSQL项目. 原始SQL和执行计划 STUDENT_BAK 表我模拟的数据,3千万行数据. ...

  10. VsCode运行与freopen与快读

    运行 g++ -o a a.cpp && ./a g++ b.cpp -o b && ./b g++ c.cpp -o c && ./c freopen ...