E题和F题两个绿题。
C - Unlucky 7
单纯的模拟一下。
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @file : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)
def check(n):
t = n
while t:
if t % 10 == 7:
return False
t //= 10
t = n
while t:
if t % 8 == 7:
return False
t //= 8
return True
def main():
items = sys.version.split()
fp = open("in.txt") if items[0] == "3.10.6" else sys.stdin
n = int(fp.readline())
ans = 0
for i in range(1, n + 1):
if check(i):
ans += 1
print(ans)
if __name__ == "__main__":
main()
D - Sum of difference
排序
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @file : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)
def main():
items = sys.version.split()
fp = open("in.txt") if items[0] == "3.10.6" else sys.stdin
n = int(fp.readline())
a = list(map(int, fp.readline().split()))
a.sort()
ans = 0
s = 0
for i in range(n):
ans += a[i] * i - s
s += a[i]
print(ans)
if __name__ == "__main__":
main()
E - Throne
如果
s
s
s不能整除
g
c
d
(
k
,
n
)
gcd(k,n)
gcd(k,n),则无解
s
+
k
x
≡
0
s + kx \equiv 0
s+kx≡0
x
=
(
n
−
s
)
∗
i
n
v
(
k
)
x=(n-s)*inv(k)
x=(n−s)∗inv(k)
此处的
i
n
v
(
k
)
inv(k)
inv(k)为
k
k
k在
n
n
n下的逆元
因为
n
n
n未必为质数,因此采用扩展gcd算法计算。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi;
void exgcd(LL a, LL b, LL& x, LL& y) {
if (!b) x = 1, y = 0;
else exgcd(b, a % b, y, x), y -= a / b * x;
}
LL gcd(LL x, LL y) {
if (x > y) {
LL temp = x;
x = y;
y = temp;
}
while (x) {
LL temp = x;
x = y % x;
y = temp;
}
return y;
}
int T;
int main() {
//freopen("in.txt", "r", stdin);
scanf("%d", &T);
while (T--) {
LL n, s, k;
scanf("%lld%lld%lld", &n, &s, &k);
LL t0 = gcd(n, k);
if (s % t0 != 0) {
printf("-1\n");
}
else {
n /= t0;
k /= t0;
s /= t0;
LL k1, y;
exgcd(k, n, k1, y);
k1 = (k1 % n + n) % n;
LL t = (n - s) * k1 % n;
printf("%lld\n", t);
}
}
return 0;
}
F - Rook on Grid
用vector记录每列格子的行位置col和每行格子的列位置row,并排序。
遍历每行。
如下面的格子中:
...#
.#..
..#.
#...
....
记r为col[1][0]
第r行之前的策略与第r行之后的策略不同
第r行之前的策略:
对于第i行,找到row[i][0]
之前的格子可以全加。之后的格子需要看上面是否有格子遮挡。row[1][0]后面的格子不需要再计算。
第r行之后的策略:
计算[1…row[1][0]]之间列未被遮挡的数量。
《是否有格子遮挡》可以用BIT维护。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi;
int h, w, m;
vi row[200020];
vi col[200020];
bool vis[200020];
LL c[200020];
inline int lowbit(int x) {
return x & -x;
}
void add(int x, int val) {
while (x <= w + 1) {
c[x] += val;
x += lowbit(x);
}
}
LL get(int x) {
LL ret = 0;
while (x > 0) {
ret += c[x];
x -= lowbit(x);
}
return ret;
}
int main() {
//freopen("in.txt", "r", stdin);
scanf("%d%d%d", &h, &w, &m);
for (int i = 0; i < m; ++i) {
int r, c;
scanf("%d%d", &r, &c);
row[r].push_back(c);
col[c].push_back(r);
}
for (int i = 1; i <= h; ++i)
{
row[i].push_back(w + 1);
sort(row[i].begin(), row[i].end());
}
for (int i = 1; i <= w; ++i) {
col[i].push_back(h + 1);
sort(col[i].begin(), col[i].end());
}
LL ans = 0;
LL r_limit = col[1][0], c_limit = row[1][0];
for (int i = 1; i < r_limit; ++i) {
for (int x : row[i]) {
if (!vis[x]) {
vis[x] = true;
add(x, 1);
}
}
LL t = row[i][0] - 1LL;
ans += t;
if (c_limit > row[i][0]) {
t = c_limit - row[i][0] - (get(c_limit) - get(row[i][0]));
ans += t;
}
}
for (int i = r_limit; i <= h; ++i) {
for (int x : row[i]) {
if (!vis[x]) {
vis[x] = true;
add(x, 1);
}
}
LL t = c_limit - get(c_limit);
ans += t;
}
printf("%lld\n", ans);
return 0;
}