• Codeforces Round #615 (Div. 3)


    Codeforces Round #615 (Div.3)

    A

    思路

    假设 (a leq b leq c) ,使三人钱币数相等首先要满足 (x geq c - a + c - b) ,其次要满足剩余量是 (3) 的整数倍。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int maxn = 1e5+10;
    const int mod = 1e9+7;
    const int maxm = 1e3+10;
    
    int tree[maxn];
    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; }
    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; }
    ll fac[maxn], inv[maxn];
    void facInit() {
        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 T, n, m;
    int a[5];
    
    int main() {
        scanf("%d", &T);
        while (T--) {
            for (int i = 1; i <= 3; ++i) scanf("%d", a+i);
            scanf("%d", &n);
            sort(a + 1, a + 1 + 3);
            ll need = 2ll * a[3] - a[2] - a[1];
            if (need <= n && (n - need) % 3 == 0) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    

    B

    思路

    显然,(R) 的字典序小于 (U) ,所以在保证能走完全部点的前提下,先往右走再往上走。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int maxn = 1e5+10;
    const int mod = 1e9+7;
    const int maxm = 1e3+10;
    
    int tree[maxn];
    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; }
    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; }
    ll fac[maxn], inv[maxn];
    void facInit() {
        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; }
    
    struct node {
        int x, y;
        inline void read() { scanf("%d%d", &x, &y); }
        inline bool operator < (const node &phs) const { return x == phs.x? y < phs.y: x < phs.x; }
    }a[maxn];
    
    int T, n, m;
    void solve() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i)
            a[i].read();
        sort(a + 1, a + 1 + n);
        bool fg = false;
        int x = 0, y = 0;
        string str = "";
        for (int i = 1; i <= n; ++i) {
            if (a[i].x >= x && a[i].y >= y) {
                for (int j = x + 1; j <= a[i].x; ++j) str.push_back('R');
                for (int j = y + 1; j <= a[i].y; ++j) str.push_back('U');
                x = a[i].x, y = a[i].y;
            } else {
                fg = 1;
                break;
            }
        }
        if (fg) puts("NO");
        else {
            puts("YES");
            cout << str << endl;
        }
    }
    
    int main() {
        scanf("%d", &T);
        while (T--)
            solve();
        return 0;
    }
    

    C

    思路

    只要 (n) 的质因子重组成三个不同数即可。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int maxn = 3e6+10;
    const int mod = 1e9+7;
    const int maxm = 1e3+10;
    const int inf = 1e9;
    
    int tree[maxn];
    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; }
    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; }
    ll fac[maxn], inv[maxn];
    void facInit() {
        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 prime[maxn], pn;
    bool nt[maxn];
    void prePrime() {
        for (int i = 2; i < maxn; ++i) {
            if (!nt[i]) prime[pn++] = i;
            for (int j = 0; j < pn && prime[j] * i < maxn; ++j) {
                nt[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
    
    struct node {
        int x, y;
        inline void read() { scanf("%d%d", &x, &y); }
        inline bool operator < (const node &phs) const { return x == phs.x? y < phs.y: x < phs.x; }
    }a[maxn];
    
    int T, n, m;
    const int block = sqrt(inf);
    
    void solve() {
        scanf("%d", &n);
        vector<int> q;
        for (int i = 0; i < pn && prime[i] <= n; ++i) {
            while(n % prime[i] == 0) {
                n /= prime[i];
                q.push_back(prime[i]);
            }
        }
        if(n > 1) q.push_back(n);
        int sz = q.size();
        if(sz < 3) puts("NO") ;
        else {
            int ans[5] = {1, 1, 1, 1, 1};
            int j = 0;
            for (int i = 1; i <= 3; ++i) {
                if (j < sz) ans[i] = q[j++];
                while(ans[i] == ans[i-1] && j < sz) ans[i] *= q[j++];
            }
            while(j < sz) ans[3] *= q[j++];
            sort(ans + 1, ans + 1 + 3);
            bool fg = false;
            for (int i = 1; i <= 3; ++i) {
                if(ans[i] == ans[i-1] || ans[i] < 2) {
                    fg = 1;
                    break;
                }
            }
            if(fg) puts("NO");
            else {
                puts("YES");
                printf("%d %d %d
    ", ans[1], ans[2], ans[3]);
            }
        }
    }
    
    int main() {
        prePrime();
        scanf("%d", &T);
        while (T--)
            solve();
        return 0;
    }
    

    D

    思路

    简单分析后,发现这是个 (m) 的剩余系,所以,每次 query 的答案模 (m) 的结果为即为 (0 sim m-1) 中出现次数最少的那个。

    我们随便用线段树维护一下即可。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int maxn = 3e6+10;
    const int mod = 1e9+7;
    const int maxm = 1e3+10;
    const int inf = 1e9;
    
    int tree[maxn];
    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; }
    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; }
    ll fac[maxn], inv[maxn];
    void facInit() {
        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 prime[maxn], pn;
    bool nt[maxn];
    void prePrime() {
        for (int i = 2; i < maxn; ++i) {
            if (!nt[i]) prime[pn++] = i;
            for (int j = 0; j < pn && prime[j] * i < maxn; ++j) {
                nt[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
    
    int T, n, m;
    
    struct node {
        int l, r, val, pos;
    }tr[maxn<<2];
    
    #define ls i<<1
    #define rs i<<1|1
    void pushup(int i) {
        if(tr[ls].val > tr[rs].val) {
            tr[i].val = tr[rs].val;
            tr[i].pos = tr[rs].pos;
        } else {
            tr[i].val = tr[ls].val;
            tr[i].pos = tr[ls].pos;
        }
    }
    
    void build(int l, int r, int i) {
        tr[i] = node{l, r, inf, inf};
        if(l == r) { tr[i].val = 0, tr[i].pos = l; return; }
        int mid = l + r >> 1;
        build(l, mid, ls); build(mid+1, r, rs);
        pushup(i);
    }
    
    void update(int pos, int i) {
        if(tr[i]. l == tr[i].r) {
            ++tr[i].val;
            return;
        }
        int mid = tr[i].l + tr[i].r >> 1;
        if(pos <= mid)  update(pos, ls);
        else update(pos, rs);
        pushup(i);
    }
    
    void solve() {
        scanf("%d%d", &n, &m);
        build(1, m, 1);
        for (int x, i = 1; i <= n; ++i) {
            scanf("%d", &x);
            x %= m; ++x;
            update(x, 1);
            printf("%d
    ", tr[1].pos-1 + m * tr[1].val);
        }
    }
    
    int main() {
            solve();
        return 0;
    }
    

    E

    思路

    题目中有两种操作:

    一、将任意一个数更改为另一个数。

    二、将某一列循环向上拨动一个位置。

    所以我们可以每一列拆开处理。

    对于每一列中的每个数,我们记录一下这个数是否应为这一列的数字,若不是则pass,若是则统计假如将他拨动到对应位置的第一行现在在第几行即可。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int maxn = 2e5+10;
    const int mod = 1e9+7;
    const int maxm = 1e3+10;
    const int inf = 1e9;
    
    int tree[maxn];
    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; }
    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; }
    ll fac[maxn], inv[maxn];
    void facInit() {
        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 prime[maxn], pn;
    bool nt[maxn];
    void prePrime() {
        for (int i = 2; i < maxn; ++i) {
            if (!nt[i]) prime[pn++] = i;
            for (int j = 0; j < pn && prime[j] * i < maxn; ++j) {
                nt[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
    
    int T, n, m;
    int cnt[maxn];
    vector<int> vec[maxn];
    
    void solve() {
        scanf("%d%d", &n, &m);
        ll res = 0;
        for (int i = 1; i <= n; ++i) for (int x, j = 1; j <= m; ++j) scanf("%d", &x), vec[j].push_back(x);
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) cnt[j] = 0;
            for (int j = 1; j <= n; ++j) {
                int x = vec[i][j-1];
                if (x % m == i % m && x <= n*m) {
                    int pos = j - (x +m-1)/ m + 1;
                    if (pos <= 0) pos += n;
                    ++cnt[pos];
                }
            }
            int sum = inf;
            for (int j = 1; j <= n; ++j) sum = min(sum, j - 1 + n - cnt[j]);
            res += sum;
        }
        printf("%lld
    ", res);
    }
    
    int main() {
        solve();
        return 0;
    }
    

    F

    思路

    抽象后的题意即为从该树找到三个节点,若他们的 (lca)(x) ,使得这三个点到 (x) 点的边的并集的数量最大。

    首先可以固定三个点中的两个点分别是树直径的两个端点,剩余的一个点则为到直径距离最远的一个点。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int maxn = 3e6+10;
    const int mod = 1e9+7;
    const int maxm = 1e3+10;
    const int inf = 1e9;
    
    int tree[maxn];
    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; }
    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; }
    ll fac[maxn], inv[maxn];
    void facInit() {
        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 prime[maxn], pn;
    bool nt[maxn];
    void prePrime() {
        for (int i = 2; i < maxn; ++i) {
            if (!nt[i]) prime[pn++] = i;
            for (int j = 0; j < pn && prime[j] * i < maxn; ++j) {
                nt[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
    
    int n;
    vector<int> g[maxn];
    bool vis[maxn];
    int f[maxn], dep[maxn];
    
    void dfs(int x, int fa = 0) {
        f[x] = fa;
        if(vis[x]) dep[x] = 1;
        else dep[x] = dep[fa] + 1;
        for (auto v: g[x]) {
            if (v == fa) continue;
            dfs(v, x);
        }
    }
    
    
    void solve() {
        scanf("%d", &n);
        for (int u, v, i = 1; i < n; ++i) {
            scanf("%d%d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
    
        int a = 0, b = 0, c = 0, ans = 0;
    
        dfs(1);
        for (int i = 1; i <= n; ++i) if (dep[i] > dep[a]) a = i;
    
        dfs(a);
        for (int i = 1; i <= n; ++i) if (dep[i] > dep[b] && i != a) b = i;
        int p = b;
        while(p) {
            vis[p] = 1;
            p = f[p];
            ++ans;
        }
        --ans;
        dfs(a);
        for (int i = 1; i <= n; ++i) if (dep[i] > dep[c] && i != a && i != b) c = i;
    
        p = c;
        while(p) {
            if (vis[p]) break;
            ++ans;
            p = f[p];
        }
    
        printf("%d
    %d %d %d
    ", ans, a, b, c);
    
    }
    
    int main() {
        solve();
        return 0;
    }
    
  • 相关阅读:
    淘宝轮播图带前后按钮
    仿淘宝轮播图 ,需要运动框架
    运动框架
    js 淡入淡出的图片
    js 分享到按钮
    js动态改变时间
    js事件委托,可以使新添加的元素具有事件(event运用)
    div高度自适应(父元素未知,所有高度跟随子元素最大的高度)
    CSS子元素居中(父元素宽高已知,子元素未知)
    css仅在指定ie浏览器生效
  • 原文地址:https://www.cnblogs.com/acerkoo/p/12236712.html
Copyright © 2020-2023  润新知