AtCoder ABC186

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+kx0
x = ( n − s ) ∗ i n v ( k ) x=(n-s)*inv(k) x=(ns)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;
}
  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值