• Codeforces Edu80


    Codeforces Edu80

    A

    题面

    思路

    显然,当 (x)(sqrt(d)) 附近时,(x + lceilfrac{d}{x+1} ceil) 较小,枚举一下即可。

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
     
    const int maxn = 1e5+10;
     
    typedef long long ll;
    ll _, n, d;
     
    int main() {
        for (scanf("%lld", &_); _; _--) {
            scanf("%lld%lld", &n, &d);
            if(d <= n) {
                puts("YES");
                continue;
            }
            ll sqt = sqrt(d)-1;
            bool fg = false;
            for (ll i = sqt; i <= 2*sqt; ++i) {
                if(i + (d+i)/(i+1) <= n) {
                    fg = 1;
                    break;
                }
            }
            puts(fg? "YES": "NO");
        }
     
        return 0;
    }
    

    B

    题面

    思路

    显然,当且仅当 (b = 9,99,999,9999 dots) 时满足条件。

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
     
    const int maxn = 1e5+10;
     
    typedef long long ll;
    ll _, A, B;
     
    int main() {
        for (scanf("%lld", &_); _; _--) {
            scanf("%lld%lld", &A, &B);
            if(B%10==9) ++B;
            int res = 0;
            while(B) {
                ++res;
                B /= 10;
            }
            printf("%lld
    ", A*(res-1));
        }
     
        return 0;
    }
    

    C

    题面

    思路:

    两个数组可拼成一个:

    (a_1, a_2, dots, a_m, b_m, b_{m-1}, dots, b_1)

    该问题可用隔板法解释: (2m) 个位置与 (n) 个数可用 (n-1) 个隔板分隔。

    最终答案:(inom{n+2m-1}{n-1})

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
     
    typedef long long ll;
    const int maxn = 1e5+10;
    const int mod = 1e9 + 7;
    ll fac[maxn], inv[maxn];
    ll _, A, B;
     
    ll ksm(ll a, ll n) {
        ll res = 1;
        while(n) {
            if(n & 1) res = res * a % mod;
            a = a * a % mod;
            n >>= 1;
        }
        return res;
    }
    void init() {
        fac[0] = 1;
        for (int i = 1; i < maxn; ++i) fac[i] = fac[i-1] * i % mod;
        inv[maxn-1] = ksm(fac[maxn-1], mod-2);
        for (int i = maxn - 2; i >= 0; --i) inv[i] = inv[i+1]*(i+1)%mod;
    }
    ll C(int n, int m) {
        return fac[n] * inv[m] % mod * inv[n-m] % mod;
    }
     
    int main() {
        init();
        int n, m;
        scanf("%d%d", &n, &m);
        printf("%lld
    ", C(n + 2 * m - 1,  n-1));
        return 0;
    }
    

    D

    题面

    思路

    二分最值。

    假设临界值为 (x),大于等于 (x) 的设为 1, 小于 (x) 的设为 0。

    则对于每个数组,可转为长度为m的01串,我们需要保证 (bit[i] | bit[j] == 2^{m}- 1) 即可

    将每一个 (bit[i]) 插入字典树中。

    对于数组 (i) ,查询是否有能满足条件的 (j) 即可。

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
     
    const int maxn = 3e5+10;
    const int inf = 0x3f3f3f3f;
     
    int n, m, a[maxn][10];
    int bit[maxn][10];
    int trie[maxn*10][2];
    int ed[maxn*10];
    int pn = 0;
     
    void insertTree(int x) {
        int p = 0;
        for (int c, i = 1; i <= m; ++i) {
            c = bit[x][i];
            if(!trie[p][c]) trie[p][c] = ++pn;
            p = trie[p][c];
        }
        ed[p] = x;
    }
    int inTree(int x) {
        int p = 0;
        for (int c, i = 1; i <= m; ++i) {
            c = 1 - bit[x][i];
            if(!trie[p][c]) {
                if(!c && trie[p][!c]) c = 1-c;
                else return false;
            }
            p = trie[p][c];
        }
        return ed[p];
    }
     
    int check(int x) {
        memset(trie, 0, sizeof(trie));
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j)
                bit[i][j] = (a[i][j] >= x);
            insertTree(i);
        }
        for (int i = 1; i <= n; ++i) {
            if(inTree(i))
                return i;
        }
        return 0;
    }
     
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j)
                scanf("%d", &a[i][j]);
        }
     
        int l = 0, r = inf;
        while(l <= r) {
            int mid = l + r >> 1;
            if(check(mid)) l = mid + 1;
            else r = mid - 1;
        }
        int ans = check(r);
        printf("%d %d
    ", ans, inTree(ans));
        return 0;
    }
    

    E

    题面

    思路

    对于一个数,若未曾主动改变过,则最小值为初始位置,否则为 1。

    对于其最大值,影响其位置的只有其左边有多少个数。因此,我们只需要用树状数组模拟其改变过程即可,只需在其主动移动或m次操作之后时,更新其最大值位置即可。

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
     
    const int maxn =6e5+10;
     
    int tree[maxn], n, m;
    inline int lowbit(int x) { return x&-x; }
    inline void modify(int x, int val) { for (int i = x; i < maxn; i += lowbit(i)) tree[i] += val; }
    inline int query(int x) {
        int res = 0;
        for (int i = x; i; i -= lowbit(i)) res += tree[i];
        return res;
    }
     
    int l[maxn], r[maxn], pos[maxn];
    int a[maxn];
     
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; ++i) scanf("%d", a+i);
        for (int i = 1; i <= n; ++i) {
            l[i] = r[i] = i;
            pos[i] = m + i;
            modify(pos[i], 1);
        }
     
        for (int x, i = 1; i <= m; ++i) {
            x = a[i];
            l[x] = 1;
            r[x] = max(r[x], query(pos[x]));
            modify(pos[x], -1);
            pos[x] = m - i + 1;
            modify(pos[x], 1);
        }
     
        for (int i = 1; i <= n; ++i) r[i] = max(r[i], query(pos[i]));
        for (int i = 1; i <= n; ++i) printf("%d %d
    ", l[i], r[i]);
     
        return 0;
    }
    
    

    F

    留坑,待补。

  • 相关阅读:
    04: Dom
    03: JavaScript基础
    02: css常用属性
    01: html常用标签
    03: Memcached
    01: Redis缓存系统
    01: RabbitMQ
    04: 事件驱动、五种I/O操作、I/O多路复用select和epoll
    03: 进程、线程、协程
    [Android] 任意时刻从子线程切换到主线程的实现
  • 原文地址:https://www.cnblogs.com/acerkoo/p/12209105.html
Copyright © 2020-2023  润新知