• Educational Codeforces Round 37 A B C D E F


    A. water the garden

    Code

    #include <bits/stdc++.h>
    #define maxn 210
    using namespace std;
    typedef long long LL;
    int n, k;
    int x[maxn];
    void work() {
        scanf("%d%d", &n,&k);
        for (int i = 0; i < k; ++i) scanf("%d", &x[i]);
        sort(x,x+k);
        int maxx = max(x[0], n-x[k-1]+1);
        for (int i = 0; i < k-1; ++i) {
            maxx = max(maxx, (x[i+1]-x[i]+2)/2);
        }
        printf("%d
    ", maxx);
    }
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) work();
        return 0;
    }
    
    

    B. Tea Queue

    题意

    若干个人排队等茶喝,每个人有到达时间和离去时间,每个时刻只能一个人喝茶。

    问每个人喝到茶的时间。

    思路

    排序,然后按顺序模拟(将当前时间逐个向后推移)

    Code

    #include <bits/stdc++.h>
    #define maxn 1010
    using namespace std;
    typedef long long LL;
    struct node {
        int l, r, id;
    }a[maxn];
    int ans[maxn];
    bool cmp(node a, node b) {
        return (a.l < b.l) || (a.l==b.l && a.id<b.id);
    }
    void work() {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) {
            scanf("%d%d", &a[i].l, &a[i].r);
            a[i].id = i;
        }
        sort(a, a+n, cmp);
        int time = 0;
        for (int i = 0; i < n; ++i) {
            if (time <= a[i].l) {
                time = a[i].l;
                ans[a[i].id] = time;
                ++time;
            }
            else {
                if (time <= a[i].r) {
                    ans[a[i].id] = time;
                    ++time;
                }
                else {
                    ans[a[i].id] = 0;
                }
            }
        }
        printf("%d", ans[0]);
        for (int i = 1; i < n; ++i) printf(" %d", ans[i]); puts("");
    }
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) work();
        return 0;
    }
    
    

    C. Swap Adjacent Elements

    题意

    给出 1-n 的一个排列,只能交换相邻两个元素,即 (i)(i+1),且只有给定的位置 (i) 才可交换。

    问能否通过交换得到一个升序序列。

    思路

    法一

    假设元素 (a[i]) 现在处在 (i) 位置,那么交换必然通过 (i-a[i]) 的一整段线段,也即要求这一整段上的点都是可交换的位置。

    即转化成一个 线段覆盖 问题,用线段树解决。

    法二

    连续的 ('1') 代表这一整段可以 (sort),将一段段 (sort) 之后判断整体是否有序即可。

    Code

    Ver. 1

    #include <bits/stdc++.h>
    #define maxn 200010
    #define lson (rt<<1)
    #define rson (lson|1)
    using namespace std;
    typedef long long LL;
    struct node { int l, r; bool flag; }tr[maxn<<2];
    char s[maxn];
    int a[maxn];
    void build(int rt, int l, int r) {
        tr[rt].l = l, tr[rt].r = r;
        if (l == r) {
            tr[rt].flag = s[l] == '1'; return;
        }
        int mid = l+r>>1;
        build(lson, l, mid); build(rson, mid+1, r);
        tr[rt].flag = tr[lson].flag & tr[rson].flag;
    }
    bool query(int rt, int l, int r) {
        if (tr[rt].l==l&&tr[rt].r==r) return tr[rt].flag;
        int mid = tr[rt].l+tr[rt].r >> 1;
        if (r <= mid) return query(lson, l, r);
        else if (l > mid) return query(rson, l, r);
        else return query(lson, l, mid) & query(rson, mid+1, r);
    }
    int main() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
        }
        scanf("%s", s+1);
        build(1, 1, n);
        for (int i = 1; i <= n; ++i) {
            if (i == a[i]) continue;
            if (i < a[i] && !query(1, i, a[i]-1)) { puts("NO"); return 0; }
            else if (i > a[i] && !query(1, a[i], i-1)) { puts("NO"); return 0; }
        }
        puts("YES");
        return 0;
    }
    
    

    Ver. 2

    #include <bits/stdc++.h>
    #define maxn 200010
    using namespace std;
    typedef long long LL;
    char s[maxn];
    int a[maxn];
    int main() {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
        scanf("%s", s);
        int l = -1; bool flag = false;
        for (int i = 0; i < n-1; ++i) {
            if (flag && s[i]=='0') {
                sort(a+l, a+i+1);
                flag = false;
            }
            else if (!flag && s[i]=='1') l = i, flag = true;
        }
        if (flag) sort(a+l, a+n);
        for (int i = 0; i < n; ++i) if (a[i]!=i+1) { puts("NO"); return 0; }
        puts("YES");
        return 0;
    }
    
    

    D. Tanks

    http://www.cnblogs.com/kkkkahlua/p/8413054.html

    E. Connected Components?

    http://www.cnblogs.com/kkkkahlua/p/8419805.html

    F. SUM and REPLACE

    题意

    对一个序列进行两种操作:

    1. ([l,r]) 中每个数 (x) 变为其约数个数 (D(x))
    2. ([l,r]) 区间求和

    思路

    神似 bzoj 3211 花神游历各国

    Code

    Ver. 1:线段树

    #include <bits/stdc++.h>
    #define maxn 300010
    #define maxl 1000010
    #define lson (rt << 1)
    #define rson (rt << 1 | 1)
    using namespace std;
    typedef long long LL;
    int prime[maxn], d[maxl], cnt[maxl], n, k, a[maxn];
    bool check[maxl];
    void init() {
        int tot = 0; d[1] = 1;
        for (int i = 2; i <= 1000000; ++i) {
            if (!check[i]) {
                prime[tot++] = i;
                d[i] = 2, cnt[i] = 1;
            }
            for (int j = 0; j < tot; ++j) {
                if (i * prime[j] > 1000000) break;
                check[i * prime[j]] = true;
                if (i % prime[j] == 0) {
                    cnt[i * prime[j]] = cnt[i] + 1;
                    d[i * prime[j]] = d[i] / (cnt[i] + 1) * (cnt[i * prime[j]] + 1);
                    break;
                }
                cnt[i * prime[j]] = 1;
                d[i * prime[j]] = d[i] << 1;
            }
        }
    }
    struct node { int l, r; bool flag; LL sum; } tr[maxn<<2];
    inline void push_up(int rt) {
        tr[rt].sum = tr[lson].sum + tr[rson].sum;
        tr[rt].flag = tr[lson].flag & tr[rson].flag;
    }
    inline int midi(int a, int b) { return a + b >> 1; }
    void build(int rt, int l, int r) {
        tr[rt].l = l, tr[rt].r = r, tr[rt].flag = 0;
        if (l == r) {
            scanf("%I64d", &tr[rt].sum);
            if (tr[rt].sum <= 2) tr[rt].flag = 1;
            return;
        }
        int mid = midi(l,r);
        build(lson, l, mid); build(rson, mid + 1, r);
        push_up(rt);
    }
    void modify(int rt, int l, int r) {
        if (tr[rt].flag) return;
        if (tr[rt].l == tr[rt].r) {
            tr[rt].sum = d[tr[rt].sum];
            if (tr[rt].sum <= 2) tr[rt].flag = 1;
            return;
        }
        int mid = midi(tr[rt].l, tr[rt].r);
        if (r <= mid) modify(lson, l, r);
        else if (l > mid) modify(rson, l, r);
        else { modify(lson, l, mid); modify(rson, mid + 1, r); }
        push_up(rt);
    }
    LL query(int rt, int l, int r) {
        if (tr[rt].l == l && tr[rt].r == r) return tr[rt].sum;
        int mid = midi(tr[rt].l, tr[rt].r);
        if (r <= mid) return query(lson, l, r);
        else if (l > mid) return query(rson, l, r);
        else return query(lson, l, mid) + query(rson, mid + 1, r);
    }
    int main() {
        scanf("%d%d", &n,&k);
        build(1, 1, n);
        init();
        while (k--) {
            int t, l, r;
            scanf("%d%d%d", &t,&l,&r);
            if (t==2) printf("%I64d
    ", query(1, l, r));
            else modify(1, l, r);
        }
        return 0;
    }
    
    

    Ver. 2:树状数组+并查集

    #include <bits/stdc++.h>
    #define maxn 300010
    #define maxl 1000010
    using namespace std;
    typedef long long LL;
    int prime[maxn], d[maxl], cnt[maxl], fa[maxn], n, k, a[maxn];
    bool check[maxl];
    LL c[maxn];
    void init() {
        int tot = 0; d[1] = 1;
        for (int i = 2; i <= 1000000; ++i) {
            if (!check[i]) {
                prime[tot++] = i;
                d[i] = 2, cnt[i] = 1;
            }
            for (int j = 0; j < tot; ++j) {
                if (i * prime[j] > 1000000) break;
                check[i * prime[j]] = true;
                if (i % prime[j] == 0) {
                    cnt[i * prime[j]] = cnt[i] + 1;
                    d[i * prime[j]] = d[i] / (cnt[i] + 1) * (cnt[i * prime[j]] + 1);
                    break;
                }
                cnt[i * prime[j]] = 1;
                d[i * prime[j]] = d[i] << 1;
            }
        }
    }
    int lowbit(int x) { return x & (-x); }
    void add(int p, int x) {
        while (p <= n) c[p] += x, p += lowbit(p);
    }
    LL query(int x) {
        LL ret = 0;
        while (x) ret += c[x], x -= lowbit(x);
        return ret;
    }
    int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
    int main() {
        init();
        scanf("%d%d", &n,&k);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            add(i, a[i]);
            fa[i] = i;
        }
        fa[n+1] = n+1;
        for (int i = 1; i <= n; ++i) if (a[i] <= 2) fa[i] = find(i+1);
        while (k--) {
            int t, l, r;
            scanf("%d%d%d", &t,&l,&r);
            if (t==2) printf("%I64d
    ", query(r)-query(l-1));
            else for (int i = find(l); i <= r; i = find(i+1)) {
                add(i, d[a[i]] - a[i]);
                if ((a[i] = d[a[i]]) <= 2) fa[i] = find(i+1);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    【高并发】面试官问我:为什么局部变量是线程安全的?
    Java中的String到底占用多大的内存空间?你所了解的可能都是错误的!!
    【高并发】学好并发编程,关键是要理解这三个核心问题
    【高并发】高并发分布式锁架构解密,不是所有的锁都是分布式锁!!
    12张图带你彻底理解分布式事务产生的场景和解决方案!!
    【高并发】面试官:讲讲高并发场景下如何优化加锁方式?
    【高并发】秒杀系统架构解密,不是所有的秒杀都是秒杀(升级版)!!
    十一长假我肝了这本超硬核PDF,现决定开源!!
    一文搞懂PV、UV、VV、IP及其关系与计算
    我把这个贼好用的Excel导出工具开源了!!
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/8407856.html
Copyright © 2020-2023  润新知