zoukankan      html  css  js  c++  java
  • 省选测试11

    省选测试 11

    T1

    题目链接

    ​ 排序 + 贪心.

    ​ 我们将(a)从大到小排序后可以得到 : (a_1 geq a_2 geq dots geq a_n).

    ​ 所以我们可以知道 : (|a_2 - a_3| + |a_4 - a_5| + dots + |a_{n-1} - a_n| < a_1).(因为(a_i geq 1))

    ​ 这个条件有什么用呢? 我们为了时选出的(a)合法, 那么就要(suma(选) > suma(未选)).

    ​ 我们要选出(frac{n}{2} +1)个数, 我们考虑这么选 : 一定选(a_1), 其余的(a_2, a_3)选一个, (a_4,a_5)选一个 ...为什么这么选呢? 由上面那个条件可以知道, 这么选一定是 (suma(选) > suma(未选)) 的.

    ​ 所以我们贪心的在每个块里选(b_i)较大的就好了.

    ​ 但是还有个问题, 万一只有选两个相邻的(b)才能满足条件怎么办? 其实这种情况不会发生, 下面是证明 :

    ​ 比如说有 : (b_1, b_2, b_3, b_4, b_5).

    ​ 只有 : (2*(b_1 +b_2 +b_3) > sumb), 没有 : (2*(b_1 + b_{2 | 3} +b_{4|5}) <= sumb)

    ​ 那么我们可以得到 : (b_1 + b_2 + b_3 > b_4 + b_5), (b_1 +b_2 + b_4 <= b_3 + b_5(2))

    ​ 既然我们按上面的方法选出了(b_1, b_2, b_4), 那么就说明 : (b_2 >= b_3, b_4 >= b_5)

    ​ 又由上面的((2))式移项可以得到 : (b_1 <= b_3 - b_2 + b_5 - b_4 < 0).

    ​ 又因为(b_1 > 0), 所以不存在这种情况.

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
    
    const int N = 1e5 + 5;
    int n, cnt;
    long long suma, sumb, tmpa, tmpb;
    struct node { int a, b, id; } x[N], tmp[N];
    
    int cmp(node x, node y) {
        return x.a > y.a;
    }
    
    int mmp(node x, node y) {
        return x.a == y.a ? x.id < y.id : x.a > y.a;
    }
    
    int main() {
    
        // freopen("game.in","r",stdin); freopen("game.out","w",stdout);
    
        n = read();
        for(int i = 1;i <= n; i++) x[i].a = read(), suma += x[i].a;
        for(int i = 1;i <= n; i++) x[i].b = read(), sumb += x[i].b;
        for(int i = 1;i <= n; i++) x[i].id = i;
        sort(x + 1, x + n + 1, cmp);
        tmpa += x[1].a; tmpb += x[1].b; tmp[++ cnt] = x[1];
        for(int i = 2;i <= n; i += 2) {
            if(x[i].b >= x[i + 1].b) tmpb += x[i].b, tmpa += x[i].a, tmp[++ cnt] = x[i];
            else tmpb += x[i + 1].b, tmpa += x[i + 1].a, tmp[++ cnt] = x[i + 1];
        }
        if(tmpb * 2 <= sumb || tmpa * 2 <= suma) { printf("-1
    "); }
        else {
            printf("%d
    ", cnt);
            sort(tmp + 1, tmp + cnt + 1, mmp);
            for(int i = 1;i <= cnt; i++) printf("%d ", tmp[i].id);
        }
    
        fclose(stdin); fclose(stdout);
    
        return 0;
    }
    

    T2

    题目链接

    ​ 这道题一看还以为是个可持久化数据结构, 没想到乱搞搞就好了.

    ​ 发现题目要求的操作十分的简单, 只需维护一下01的个数就好了, 所以我们完全没必要去写可持久化.

    ​ 对于操作是1,2,3类型的, 我们直接往它的上一次操作连边, 对于操作是4类型的, 我们往它要返回的那一次操作连边, 这样就构成了一颗操作树, 我们直接在这颗操作树上(dfs)就可以了.

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
    
    const int M = 1e3 + 5, K = 1e5 + 5;
    int n, m, q_, res, cnt;
    int col[M][M], Col[M], num[M], ans[K], head[K];
    struct ques { int opt, x, y, f; } q[K];
    struct edge { int to, nxt; } e[K << 1];
    
    void add(int x, int y) {
        // cout << x << " " << y << "!!!!
    ";
        e[++ cnt].nxt = head[x]; head[x] = cnt; e[cnt].to = y;
    }
    
    void Work(int now, int f) {
        // cout << now << " " << f << "------->";
        if(f == 0) {
            if(q[now].opt == 2) {
                if(!Col[q[now].x]) {
                    if(col[q[now].x][q[now].y]) {
                        num[q[now].x] --; res --; col[q[now].x][q[now].y] = 0;
                    }
                    else q[now].f = 1;
                }
                else {
                    if(!col[q[now].x][q[now].y]) {
                        num[q[now].x] ++; res --; col[q[now].x][q[now].y] = 1;
                    }
                    else q[now].f = 1;
                }
            }
            if(q[now].opt == 1) {
                if(!Col[q[now].x]) {
                    if(!col[q[now].x][q[now].y]) {
                        num[q[now].x] ++; res ++; col[q[now].x][q[now].y] = 1;
                    }
                    else q[now].f = 1;
                }
                else {
                    if(col[q[now].x][q[now].y]) {
                        num[q[now].x] --; res ++; col[q[now].x][q[now].y] = 0;
                    }
                    else q[now].f = 1;
                }
            }
            if(q[now].opt == 3) {
                if(!Col[q[now].x]) res -= num[q[now].x], res += m - num[q[now].x];
                else res -= m - num[q[now].x], res += num[q[now].x];
                Col[q[now].x] ^= 1;
            }
        }
        else {
            if(q[now].opt == 2) {
                if(!Col[q[now].x]) {
                    if(!q[now].f) {
                        num[q[now].x] ++; res ++; col[q[now].x][q[now].y] = 1;
                    }
                }
                else {
                    if(!q[now].f) {
                        num[q[now].x] --; res ++; col[q[now].x][q[now].y] = 0;
                    }
                }
            }
            if(q[now].opt == 1) {
                if(!Col[q[now].x]) {
                    if(!q[now].f) {
                        num[q[now].x] --; res --; col[q[now].x][q[now].y] = 0;
                    }
                }
                else {
                    if(!q[now].f) {
                        num[q[now].x] ++; res --; col[q[now].x][q[now].y] = 1;
                    }
                }
            }
            if(q[now].opt == 3) {
                if(!Col[q[now].x]) res -= num[q[now].x], res += m - num[q[now].x];
                else res -= m - num[q[now].x], res += num[q[now].x];
                Col[q[now].x] ^= 1;
            }
        }
        // cout << res << "
    ";
    }
    
    void dfs(int x) {
        // cout << x << "++++++
    ";
        Work(x, 0); ans[x] = res;
        // cout << x << " " << ans[x] << " " << res << "+++
    ";
        for(int i = head[x]; i ; i = e[i].nxt) dfs(e[i].to);
        Work(x, 1);
        // cout << x << " " << ans[x] << " " << res << "---
    ";
    }
    
    int main() {
    
        // freopen("now.in","r",stdin); freopen("now.out","w",stdout);
    
        n = read(); m = read(); q_ = read();
        for(int i = 1;i <= q_; i++) {
            q[i].opt = read(); q[i].x = read();
            if(q[i].opt <= 2) q[i].y = read();
            if(q[i].opt == 4) {
                add(q[i].x, i);
            }
            else add(i - 1, i);
        }
        dfs(0);
        for(int i = 1;i <= q_; i++) printf("%d
    ", ans[i]); 
    
        fclose(stdin); fclose(stdout);
    
        return 0;
    }
    
    /*
    2 3 4 
    1 1 1 
    3 2 
    4 0 
    1 1 1
    
    999 999 12
    2 693 492
    1 639 609
    4 1
    4 0
    1 419 528
    3 223
    1 1 36
    4 6
    1 75 3
    1 327 629
    4 8
    2 222 216
    */
    

    T3

    题目链接

    ​ 欧拉回路.

    ​ 由于一些区间是这样的 : ([x,x]). 也就是只覆盖一个点, 我们不太好操作, 于是我们把点转化成线段, 那么每一个区间就变成了([x,x+1])([x,y+1])了, 这样比较舒服.

    ​ 我们把红色区间看成+1, 绿色区间看成-1, 最后我们需要每个点(|sum p_i| leq 1).

    ​ 不会了..............

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
    
    const int N = 2e5 + 5;
    int n, cnt, cnt_b;
    int b[N], c[N], s[N], t[N], vis[N], head[N], in_du[N], out_du[N];
    struct line { int l, r; } L[N];
    struct edge { int f, id, to, nxt; } e[N << 1];
    
    void add(int x, int y, int i) {
        e[++ cnt].nxt = head[x]; head[x] = cnt; e[cnt].to = y; e[cnt].id = i;
    }
    
    void dfs(int x) {
        vis[x] = 1;
        for(int i = head[x]; i ; i = e[i].nxt) {
            int y = e[i].to; if(e[i].f) continue ;
            s[e[i].id] = x; t[e[i].id] = y;
            e[i].f = e[i ^ 1].f = 1;
            // cout << x << " " << y << "
    ";
            dfs(y);
        }
    }
    
    int main() {
    
        // freopen("party.in","r",stdin); freopen("party.out","w",stdout);
        
        n = read(); cnt = 1;
        for(int i = 1;i <= n; i++) {
            L[i].l = read(), L[i].r = read() + 1; 
            b[++ cnt_b] = L[i].l, b[++ cnt_b] = L[i].r;
        }
        sort(b + 1, b + cnt_b + 1);
        cnt_b = unique(b + 1, b + cnt_b + 1) - b - 1;
        for(int i = 1;i <= n; i++) {
            L[i].l = lower_bound(b + 1, b + cnt_b + 1, L[i].l) - b;
            L[i].r = lower_bound(b + 1, b + cnt_b + 1, L[i].r) - b;
            add(L[i].l, L[i].r, i); add(L[i].r, L[i].l, i);
            out_du[L[i].l] ++; in_du[L[i].r] ++;
        }
        for(int i = 1;i <= cnt_b; i++) {
            c[i] = c[i - 1] + out_du[i] - in_du[i];
            if(c[i] & 1) 
                add(i, i + 1, n + 1), add(i + 1, i, n + 1);
        }
        for(int i = 1;i <= cnt_b; i++) if(!vis[i]) dfs(i);
        for(int i = 1;i <= n; i++) 
            printf("%d ", s[i] < t[i] ? 0 : 1);
    
        // fclose(stdin); fclose(stdout);
    
        return 0;
    }
    
    /*
    2
    0 2 
    2 3
    
    6
    1 5 
    1 3 
    3 5 
    2 10 
    11 11 
    12 12
    */
    
  • 相关阅读:
    Python编程题32最小栈
    Python编程题31用列表实现队列
    Python编程题34用队列实现栈
    Python编程题40验证字母表的顺序
    Python编程题36三个数的最大乘积
    Python编程题39所有奇数长度子列表的和
    RTX 3090的深度学习环境配置指南:Pytorch、TensorFlow、Keras。配置显卡
    python numpy实现SVD 矩阵分解
    linux安装tomcat部署静态网页
    python使用deepwalk模型算节点相似度
  • 原文地址:https://www.cnblogs.com/czhui666/p/14526668.html
Copyright © 2011-2022 走看看