赛码"BestCoder"杯中国大学生程序设计冠军赛

今天终于有时间补题了。。06神数论没补。

01:贪心的思路,扫3遍,尽量找右区间小的

02:这里用的是kuangbin神的黑科技,并查集,把一个点拆成一个奇数点和偶数点,每次连边就奇数边和偶数边连,如果出现一个点自己的奇数和偶数点在一个集合中就是有奇环,如果在加一条边的时候,这条边已经在一个集合了,那么肯定会出现偶环(如果本来是奇环,加一条边进去必然出现偶环)

03:和官方题解一个思路,主要要想到最终答案其实就一种情况而已,就很好计算了,跟概率无关

04:这题线段树的方法挺机智了,自己只想到了nlog(n)log(n)看了官方题解才焕然大悟,可以利用括号的增加的单调性在线段树中进行二分查找

05:约瑟夫环公式+背包,比较水的一题

07:这题官方题解是折半搜,我是用了DP的思路,然后加一些剪枝,因为如果一个性格只出现一次,这个必然要选,那么相应的长相也要选,如果长相有必须选两次,必然就没有答案了,那么这些必然要选的筛走,在剩下的人物中做背包,利用map存状态,dp[i][s][b]表示的是第i个人,性格集合为s,异或和为b的情况数,第一维可以滚动掉

08:树剖,要利用一个性质,处理子树其实就是利用dfs序,一个子树必然是一个连续区间,剩下就树链剖分搞搞了

09:搜过去了。。每条边只走一次,这样复杂度是O(E),官方题解的方法比较科学。。就是先并查集缩点,然后在连有向边拓扑找环

10:每次一个区间,相应数字变成和这个区间的lcm,然后最后求出了数组,在去和原询问判断一下,如果完全一样就是解

代码:

01:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const ll MOD = 4294967296LL;

int t, n, a, b, c, d;
ll l, r, x, y;

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%I64d%I64d%d%d%d%d", &n, &l, &r, &a, &b, &c, &d);
        int cnt = 0;
        ll pre;
        for (int k = 0; k < 3; k++) {
            ll Minr = MOD;
            x = l, y = r;
            for (int i = 0; i < n; i++) {
                if (x > y) {
                    if (k == 0 || y > pre)
                    Minr = min(Minr, x);
                } else {
                    if (k == 0 || x > pre)
                    Minr = min(Minr, y);
                }
                x = (ull)x * a % MOD + b;
                if (x > MOD) x -= MOD;
                y = (ull)y * c % MOD + d;
                if (y > MOD) y -= MOD;
            }
            if (Minr != MOD) cnt++;
            else break;
            pre = Minr;
        }
        if (cnt == 3) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

02:

#include <cstdio>
#include <cstring>

const int N = 200005;
int t, n, m;
int parent[N];

int find(int x) {
    if (parent[x] == x) return x;
    return parent[x] = find(parent[x]);
}

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < 2 * n; i++) parent[i] = i;
        int u, v;
        int ans1 = 0, ans2 = 0;
        while (m--) {
            scanf("%d%d", &u, &v);
            u--; v--;
            int pu = find(u * 2);
            int pv = find(v * 2 + 1);
            if (pu == pv) ans2 = 1;
            if (pu != pv) {
                parent[pu] = pv;
                parent[find(u * 2 + 1)] = find(v * 2);
            }
        }
        for (int i = 0; i < n; i++) {
            if (find(i * 2) == find(i * 2 + 1)) {
                ans1 = 1;
                break;
            }
        }
        printf("%s\n%s\n", ans1 ? "YES" : "NO", ans2 ? "YES" : "NO");
    }
    return 0;
}

03:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 55;

int t, n, m;
int a[N], b[N];

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < m; i++) scanf("%d", &a[i]);
        for (int i = 0; i < m; i++) scanf("%d", &b[i]);
        sort(a, a + m);
        sort(b, b + m);
        int flag = 0;
        for (int i = 0; i < m; i++) {
            if (a[i] > b[i]) {
                flag = 1;
                break;
            }
        }
        if (flag) printf("Stupid BrotherK!\n");
        else {
            int ans = max(a[0] - 1, n - b[m - 1]);
            for (int i = 1; i < m; i++)
                ans = max(ans, a[i] - b[i - 1] - 1);
            printf("%.6f\n", ans * 1.0);
        }
    }
    return 0;
}

04:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 200005;

int t, n, q;

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

struct Node {
    int l, r, cnt[2];
} node[N * 4];

char str[N];

void pushup(int x) {
    int tmp = min(node[lson(x)].cnt[0], node[rson(x)].cnt[1]);
    node[x].cnt[0] = node[lson(x)].cnt[0] - tmp + node[rson(x)].cnt[0];
    node[x].cnt[1] = node[rson(x)].cnt[1] - tmp + node[lson(x)].cnt[1];
}

void build(int l, int r, int x = 0) {
    node[x].l = l; node[x].r = r;
    if (l == r) {
        node[x].cnt[0] = node[x].cnt[1] = 0;
        node[x].cnt[str[l] == ')'] = 1;
        return;
    }
    int mid = (l + r) / 2;
    build(l, mid, lson(x));
    build(mid + 1, r, rson(x));
    pushup(x);
}

void modify(int v, int x = 0) {
    if (node[x].l == node[x].r) {
        swap(node[x].cnt[0], node[x].cnt[1]);
        return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    if (v <= mid) modify(v, lson(x));
    else modify(v, rson(x));
    pushup(x);
}

int ln, rn, flag;

void query(int l, int r, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
        int tmp = min(ln, node[x].cnt[1]);
        ln += node[x].cnt[0] - tmp; rn += node[x].cnt[1] - tmp;
        return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) query(l, r, lson(x));
    if (r > mid) query(l, r, rson(x));
}

void get1(int l, int r, int k, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
        int tmp = min(ln, node[x].cnt[1]);
        if (node[x].l == node[x].r) {
            if (rn + node[x].cnt[1] - tmp == k) {
                flag = node[x].l;
                return;
            }
        }
        if (rn + node[x].cnt[1] - tmp >= k) {
            get1(l, r, k, lson(x));
            if (flag) return;
            get1(l, r, k, rson(x));
            return;
        }
        rn += node[x].cnt[1] - tmp;
        ln += node[x].cnt[0] - tmp;
        return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) {
        get1(l, r, k, lson(x));
        if (flag) return;
    }
    if (r > mid) get1(l, r, k, rson(x));
}

void get2(int l, int r, int k, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
        int tmp = min(rn, node[x].cnt[0]);
        if (node[x].l == node[x].r) {
            if (ln + node[x].cnt[0] - tmp == k) {
                flag = node[x].l;
                return;
            }
        }
        if (ln + node[x].cnt[0] - tmp >= k) {
            get2(l, r, k, rson(x));
            if (flag) return;
            get2(l, r, k, lson(x));
            return;
        }
        rn += node[x].cnt[1] - tmp;
        ln += node[x].cnt[0] - tmp;
        return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    if (r > mid) {
        get2(l, r, k, rson(x));
        if (flag) return;
    }
    if (l <= mid)
        get2(l, r, k, lson(x));
}

inline void scanf_(int &num)//无负数
{
    char in;
    while((in=getchar()) > '9' || in<'0') ;
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
}

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf_(n); scanf_(q);
        scanf("%s", str + 1);
        build(1, n);
        int tp, x, l, r, k;
        while (q--) {
            scanf("%d", &tp);
            if (tp == 1) {
                scanf_(x);
                modify(x);
            } else {
                scanf_(l); scanf_(r); scanf_(k);
                ln = 0, rn = 0;
                query(l, r);
                if (k > ln + rn) printf("-1\n");
                else {
                    int tl = ln, tr = rn;
                    ln = rn = flag = 0;
                    if (k > tr) get2(l, r, tl + tr - k + 1);
                    else get1(l, r, k);
                    printf("%d\n", flag);
                }
            }
        }
    }
    return 0;
}

05:

#include <cstdio>
#include <cstring>

const int N = 205;
int t, n, m, a[N];
int dp[N][N];
int ans[N], an;

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < m; i++)
            scanf("%d", &a[i]);
        memset(dp, 0, sizeof(dp));
        dp[1][0] = 1;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int k = 0; k < i; k++) {
                    if (dp[i][k]) dp[i + 1][(k + a[j]) % (i + 1)] = 1;
                }
            }
        }
        an = 0;
        for (int i = 0; i < n; i++) {
            if (dp[n][i]) ans[an++] = i;
        }
        printf("%d\n", an);
        for (int i = 0; i < an; i++)
            printf("%d%c", ans[i] + 1, i == an - 1 ? '\n' : ' ');
    }
    return 0;
}

06:没写

07:

#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
using namespace std;

const int N = 35;

int n;
typedef long long ll;

struct SB {
    int c, m;
    SB() {}
    SB(int c, int m) {
        this->c = c;
        this->m = m;
    }
};

int t;

vector<SB> g[N], gg[N];
int to[N], tn;

typedef pair<ll, int> pii;
map<pii, ll> dp[2];
map<pii, ll>::iterator it;
int must[N];

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            g[i].clear();
            gg[i].clear();
            must[i] = 0;
        }
        int a, b, c;
        tn = 0;
        memset(to, -1, sizeof(to));
        for (int i = 1; i <= n; i++) {
            scanf("%d%d%d", &a, &b, &c);
            if (to[b] == -1) to[b] = tn++;
            g[a].push_back(SB(b, c));
            gg[b].push_back(SB(a, c));
        }
        int flag = 0;
        ll s1 = 0; int s2 = 0;
        for (int i = 1; i <= n; i++) {
            if (gg[i].size() == 1) {
                if (must[gg[i][0].c] == 1) {
                    flag = 1;
                    break;
                }
                s1 |= (1LL<<to[i]);
                s2 ^= gg[i][0].m;
                must[gg[i][0].c] = 1;
            }
        }
        if (flag) {
            printf("0\n");
            continue;
        }
        int pre = 0, now = 1;
        dp[now].clear(); dp[now][make_pair(s1, s2)] = 1;
        for (int i = 1; i <= n; i++) {
            if (g[i].size() == 0 || must[i]) continue;
            swap(now, pre);
            dp[now] = dp[pre];
            for (it = dp[pre].begin(); it != dp[pre].end(); it++) {
                pii x = it->first;
                ll w = it->second;
                for (int j = 0; j < g[i].size(); j++) {
                    pii xx = x;
                    xx.first |= (1LL<<(to[g[i][j].c]));
                    xx.second ^= g[i][j].m;
                    dp[now][xx] += w;
                }
            }
        }
        printf("%I64d\n", dp[now][make_pair((1LL<<tn) - 1, 0)]);
    }
    return 0;
}

08:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 100005;
const int M = 200005;
#pragma comment(linker, "/STACK:1024000000,1024000000")

void scanf_(int &num) {
    char in;
    bool neg=false;
    while(((in=getchar()) > '9' || in<'0') && in!='-') ;
    if(in=='-')
    {
        neg=true;
        while((in=getchar()) >'9' || in<'0');
    }
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
    if(neg)
        num=0-num;
}

int dep[N], fa[N], son[N], sz[N], top[N], id[N], idx, to[N], val[N], val2[N];
int head[N], nxt[M], edge[M], en;


void init() {
    en = 0;
    idx = 0;
    memset(head, -1, sizeof(head));
}

void add_Edge(int u, int v) {
    edge[en] = v;
    nxt[en] = head[u];
    head[u] = en++;
}

void dfs1(int u, int f, int d) {
    dep[u] = d;
    sz[u] = 1;
    fa[u] = f;
    son[u] = 0;
    for (int i = head[u]; i + 1; i = nxt[i]) {
        int v = edge[i];
        if (v == f) continue;
        dfs1(v, u, d + 1);
        sz[u] += sz[v];
        if (sz[son[u]] < sz[v])
            son[u] = v;
    }
}

void dfs2(int u, int tp) {
    id[u] = ++idx;
    val2[idx] = val[u];
    top[u] = tp;
    if (son[u]) dfs2(son[u], tp);
    for (int i = head[u]; i + 1; i = nxt[i]) {
        int v = edge[i];
        if (v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
    to[u] = idx;
}

int t, n;

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

struct Node {
    int l, r, sum, lazy;
    void gao() {
        sum = 0;
        lazy = 1;
    }
} node[N * 4];

void pushup(int x) {
    node[x].sum = node[lson(x)].sum + node[rson(x)].sum;
}

void pushdown(int x) {
    if (node[x].lazy) {
        node[lson(x)].gao();
        node[rson(x)].gao();
        node[x].lazy = 0;
    }
}

void build(int l, int r, int x = 0) {
    node[x].l = l; node[x].r = r; node[x].lazy = 0;
    if (l == r) {
        node[x].sum = val2[l];
        return;
    }
    int mid = (l + r) / 2;
    build(l, mid, lson(x));
    build(mid + 1, r, rson(x));
    pushup(x);
}

void add(int l, int r, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
        node[x].gao();
        return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    pushdown(x);
    if (l <= mid) add(l, r, lson(x));
    if (r > mid) add(l, r, rson(x));
    pushup(x);
}

void add2(int v, int w, int x = 0) {
    if (node[x].l == node[x].r) {
        node[x].sum += w;
        return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    pushdown(x);
    if (v <= mid) add2(v, w, lson(x));
    if (v > mid) add2(v, w, rson(x));
    pushup(x);
}

int query(int l, int r, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) return node[x].sum;
    int mid = (node[x].l + node[x].r) / 2;
    int ans = 0;
    pushdown(x);
    if (l <= mid) ans += query(l, r, lson(x));
    if (r > mid) ans += query(l, r, rson(x));
    pushup(x);
    return ans;
}

void gaoadd(int u, int v) {
    int tp1 = top[u], tp2 = top[v];
    while (tp1 != tp2) {
        if (dep[tp1] < dep[tp2]) {
            swap(tp1, tp2);
            swap(u, v);
        }
        add(id[tp1], id[u]);
        u = fa[tp1];
        tp1 = top[u];
    }
    if (dep[u] > dep[v]) swap(u, v);
    add(id[u], id[v]);
}

int gaoquery(int u, int v) {
    int ans = 0;
    int tp1 = top[u], tp2 = top[v];
    while (tp1 != tp2) {
        if (dep[tp1] < dep[tp2]) {
            swap(tp1, tp2);
            swap(u, v);
        }
        ans += query(id[tp1], id[u]);
        u = fa[tp1];
        tp1 = top[u];
    }
    if (dep[u] > dep[v]) swap(u, v);
    ans += query(id[u], id[v]);
    return ans;
}

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        init();
        for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
        int u, v;
        for (int i = 1; i <= n - 1; i++) {
            scanf_(u);
            scanf_(v);
            add_Edge(u, v);
            add_Edge(v, u);
        }
        dfs1(1, 1, 0);
        dfs2(1, 1);
        build(1, n);
        int qn;
        scanf("%d", &qn);
        int ans = 0;
        while (qn--) {
            int tp, a, b;
            scanf("%d%d", &tp, &a);
            if (tp == 1) {
                scanf("%d", &b);
                ans += gaoquery(a, b);
                gaoadd(a, b);
            } else if (tp == 2) {
                if (query(id[a], id[a]) == 0) {
                    add2(id[a], val2[id[a]]);
                    ans -= val2[id[a]];
                }
            }
            else if (tp == 3) {
                ans += query(id[a], to[a]);
                add(id[a], to[a]);
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

09:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;

const int N = 1000005;

int t;

int n, m1, m2, vis[3 * N], vis2[N], vv[N];

struct Edge {
    int v, tp;
    Edge() {}
    Edge(int v, int tp) {
        this->v = v;
        this->tp = tp;
    }
} edge[N * 3];

int head[N], nxt[N * 3], en;

inline void scanf_(int &num) {
    char in;
    while((in=getchar()) > '9' || in<'0') ;
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
}

void add(int u, int v, int tp) {
    vis[en] = 0;
    edge[en] = Edge(v, tp);
    nxt[en] = head[u];
    head[u] = en++;
}

bool dfs(int u) {
    if (vis2[u]) return true;
    vv[u] = 1;
    vis2[u] = 1;
    for (int i = head[u]; i + 1; i = nxt[i]) {
        if (vis[i]) continue;
        int v = edge[i].v;
        int tp = edge[i].tp;
        if (tp == 1) vis[i] = vis[i^1] = 1;
        else vis[i] = 1;
        if (dfs(v)) return true;
        if (tp == 1) vis[i] = vis[i^1] = 0;
        else vis[i] = 0;
    }
    vis2[u] = 0;
    return false;
}

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d%d", &n, &m1, &m2);
        en = 0;
        for (int i = 1; i <= n; i++) {
            head[i] = -1;
            vis2[i] = 0;
            vv[i] = 0;
        }
        int u, v;
        while (m1--) {
            scanf_(u);
            scanf_(v);
            add(u, v, 1);
            add(v, u, 1);
        }
        while (m2--) {
            scanf_(u);
            scanf_(v);
            add(u, v, 0);
        }
        int flag = 0;
        for (int i = 1; i <= n; i++)
            if (!vv[i] && dfs(i)) {
                flag = 1;
                break;
            }
        printf("%s\n", flag ? "YES" : "NO");
    }
    return 0;
}

10:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;
const int N = 1005;
int t, n, q;
ll a[N];

ll gcd(ll a, ll b) {
    if (!b) return a;
    return gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

int l[N], r[N];
ll ans[N];

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &q);
        for (int i = 1; i <= n; i++) a[i] = 1;
        for (int i = 0; i < q; i++) {
            scanf("%d%d%I64d", &l[i], &r[i], &ans[i]);
            for (int j = l[i]; j <= r[i]; j++)
                a[j] = lcm(a[j], ans[i]);
        }
        int flag = 1;
        for (int i = 0; i < q; i++) {
            ll tmp = 0;
            for (int j = l[i]; j <= r[i]; j++)
                tmp = gcd(tmp, a[j]);
            if (tmp != ans[i]) {
                flag = 0;
                break;
            }
        }
        if (flag) {
            for (int i = 1; i <= n; i++)
                printf("%I64d%c", a[i], i == n ? '\n' : ' ');
        } else printf("Stupid BrotherK!\n");
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要设计一个程序来解决算法淘汰赛冠军问题,可以采用以下步骤: 1. 输入选手数量 n 和比赛结果列表 results。 2. 初始化一个长度为 n 的数组 scores,用来记录每个选手的得分。 3. 遍历比赛结果列表 results,对每一场比赛的胜者和失败者分别加上相应的得分。例如,如果 A 战胜了 B,那么 A 的得分加上 3 分,B 的得分加上 0 分。 4. 对得分数组 scores 进行排序,找到得分最高的选手,即为冠军。 5. 输出冠军的编号和得分。 以下是一个示例代码: ``` #include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int n; cin >> n; vector<int> scores(n, 0); vector<pair<int, int>> results; for (int i = 0; i < n * (n - 1) / 2; i++) { int a, b, c; cin >> a >> b >> c; if (c == 1) { scores[a - 1] += 3; } else if (c == 0) { scores[a - 1]++; scores[b - 1]++; } else { scores[b - 1] += 3; } } int max_score = *max_element(scores.begin(), scores.end()); int champion = find(scores.begin(), scores.end(), max_score) - scores.begin() + 1; cout << champion << " " << max_score << endl; return 0; } ``` 在这个示例代码中,我们使用了一个 vector 来存储每个选手的得分,使用了一个 pair 来存储每场比赛的结果。在输入比赛结果时,如果胜者获得了 1 分,败者获得了 0 分;如果是平局,每个选手都获得了 1 分。最后,我们使用 STL 中的 max_element 函数找到得分最高的选手,并计算其编号和得分。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值