• Codeforces #670 div2


    A

    水题,直接模拟能填就填。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 1e6+10;
    
    ll N, M, T, t[MAXN];
    
    int main() {
        scanf("%lld", &T);
        while (T--) {
            for (ll i = 0; i <= 100; i++) t[i] = 0;
            scanf("%lld", &N);
            for (ll tem, i = 1; i <= N; i++) {
                scanf("%lld", &tem);
                t[tem]++;
            }
            ll ans = 0;
            for (ll i = 0; i <= 100; i++) {
            	if (t[i]) {
            		t[i]--;	
            	} else {
            		ans += i;
            		break;
    			}
            }
            for (ll i = 0; i <= 100; i++) {
            	if (t[i]) {
    				t[i]--;
    			} else {
    				ans += i;
    				break;	
    			}
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

    B

    先排序,然后 前5个,前4个后1个,前3个后2个,前2个后3个,前1个后4个,后5个 六种方案取max就行。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 1e6+10;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    
    ll N, T, val[MAXN];
    
    ll Max(); 
    
    int main() {
        scanf("%lld", &T);
        while (T--) {
            scanf("%lld", &N);
            for (ll i = 1; i <= N; i++) {
                scanf("%lld", val+i);
            }
            sort(val+1, val+N+1);
            ll ans = Max();
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
    ll Max() {
        ll ret = -INF;
        ret = max(val[1] * val[2] * val[3] * val[4] * val[5], ret);
        ret = max(val[1] * val[2] * val[3] * val[4] * val[N], ret);
        ret = max(val[1] * val[2] * val[3] * val[N-1] * val[N], ret);
        ret = max(val[1] * val[2] * val[N-2] * val[N-1] * val[N], ret);
        ret = max(val[1] * val[N-3] * val[N-2] * val[N-1] * val[N], ret);
        ret = max(val[N-4] * val[N-3] * val[N-2] * val[N-1] * val[N], ret);
        return ret;
    }
    

    C

    直接找到重心,如果只有一个随便输出一条边两次就行。
    否则在一个重心的子树切一根然后接到另一个重心上。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 1e6+10;
    
    struct edge {
        ll nt, to;
    } E[MAXN];
    
    ll N, M, T, cnt = -1, head[MAXN], siz[MAXN], fa[MAXN], w[MAXN];
    ll root, other, del;
    
    void add(ll, ll);
    void dfs(ll, ll);
    ll gtl(ll);
    
    int main() {
        scanf("%lld", &T);
        while (T--) {
            scanf("%lld", &N);
            root = 0, del = 0, other = 0;
            for (ll i = 1; i <= N; i++) {
                head[i] = -1;
                siz[i] = 0;
                w[i] = 0;
                fa[i] = 0;
            }
            cnt = -1;
            ll tem1, tem2;
            for (ll x, y, i = 1; i < N; i++) {
                scanf("%lld%lld", &x, &y);
                add(x, y);
                add(y, x);
                tem1 = x, tem2 = y;
            }
            dfs(1, 0);
            if (!other) {
                printf("%lld %lld
    ", tem1, tem2);
                printf("%lld %lld
    ", tem1, tem2);
            } else {
                if (fa[other] == root) swap(root, other);
            	ll del = gtl(root);
                printf("%lld %lld
    ", del, fa[del]);
                printf("%lld %lld
    ", del, other);
            }
        }
        return 0;
    }
    
    ll gtl(ll n) {
    	bool flag = 0;
    	for (ll i = head[n]; ~i; i = E[i].nt) {
    		ll v = E[i].to;
    		if (v == fa[n]) continue;
    		else {
    			return gtl(v);
    			flag = 1;	
    		}
    	}
    	if (!flag) return n; 
    }
    
    void dfs(ll n, ll ff) {
        fa[n] = ff;
        for (ll i = head[n]; ~i; i = E[i].nt) {
            ll v = E[i].to;
            if (v == ff) continue;
            else {
                dfs(v, n);
                siz[n] += siz[v];
                w[n] = max(w[n], siz[v]);
            }
        }
        siz[n]++;
        w[n] = max(w[n], N - siz[n]);
        if (root == 0 || w[root] > w[n]) root = n, other = 0;
        else if (w[root] == w[n]) other = n;
    }
    
    void add(ll x, ll y) {
        cnt++;
        E[cnt].to = y;
        E[cnt].nt = head[x];
        head[x] = cnt;
    }
    
    /*
    1
    5
    1 2
    2 3
    3 4
    2 5
    18
    1 2
    1 3
    3 4
    4 5
    5 6
    6 7
    7 8
    8 9
    9 10
    2 11
    11 12
    11 13
    2 14
    14 15
    2 16
    16 18
    16 17
    
    */
    

    D

    先差分,然后我们可以知道序列的最大值一定是 (b_n) 或者 (c_1) 那么我们就让这俩最接近就好。
    那么我们可以考虑
    (a_i > a_{i-1})(b_{i} = b_{i-1} + a_i - a_{i-1})
    (a_i < a_{i-1})(c_{i} = c_{i-1} + a_i - a_{i-1})
    那么我们令 (K = sum_{i=2}^N max(a_i - a_{i-1}, 0))(c_1 = x)
    那么 原题即为求解 (max(x, a_1-x+K))
    那么我们令 (x)(a_1-x+K) 尽可能接近即可。
    答案即为 (lceil frac{a_1+K}{2} ceil)
    对于一个修改,我们发现只会修改到 (a_l-a_{l-1})(a_{r+1} - a_r) 的值
    那么只需要在相应的位置修改并将影响加至 (K) 即可。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 1e6+10;
    
    ll N, M, T, val[MAXN], del[MAXN], sum;
    
    ll ans(ll);
    void upd(ll, ll);
    
    int main() {
        scanf("%lld", &N);
        for (ll i = 1; i <= N; i++) {
            scanf("%lld", val+i);
            del[i] = val[i] - val[i-1];
            if (i != 1 && del[i] > 0) sum += del[i];
        }
        printf("%lld
    ", ans(val[1] + sum));
        scanf("%lld", &M);
        for (ll i = 1, l, r, d; i <= M; i++) {
            scanf("%lld%lld%lld", &l, &r, &d);
            if (l == 1) val[1] += d;
            else {
                upd(l, d);
            }
            if (r != N) {
                upd(r+1, -d);
            }
            printf("%lld
    ", ans(val[1] + sum));
        }
        return 0;
    }
    
    void upd(ll pos, ll v) {
        ll bef = max(del[pos], 0LL);
        del[pos] += v;
        sum += max(del[pos], 0LL) - bef;
    } 
    
    ll ans(ll x) {
        if (x >= 0) return (x + 1) / 2;
        else return x / 2;
    }
    
    Yukkuri si te yi te ne
  • 相关阅读:
    本周读书的感想
    程序员应知——学习、思考与分享
    用设计版面的思想编写漂亮的代码
    程序员应知——你有几种武器
    《明星DBA成长之路》读后随想
    有些东西不可替代
    DB2连接串&DB2客户端连接服务端
    数据库连接字符串备忘大全
    ASP Blob类型转存为Long Raw类型
    Oracle read_csv
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/13663762.html
Copyright © 2020-2023  润新知