Codeforces contest 787 recordings

比赛记录


A - The Monster

Problem Description

i使x=i×a+bx=j×c+d

Data Limit

a,b,c,d<100

Solution

exgcd

Code

#include<cstdio>
#include<iostream>
using namespace std;
int main() {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    for(int i = 0; i <= 10000; i ++) {
        while(b < d) b += a;
        while(b > d) d += c;
        if(b == d) {
            printf("%d\n", b);
            return 0;
        }
    }
    printf("-1\n");
    return 0;
}

B - Not Afraid

Problem Description

mYES

Data Limit

mi=1ki104

Solution

Code

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
bool tab[50005];
int main() {
    int n, m, k, x;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i ++) {
        memset(tab, 0, sizeof(tab));
        scanf("%d", &k);
        bool flag = 0;
        while (k --) {
            scanf("%d", &x);
            if (tab[20000 - x]) flag = 1;
            tab[20000 + x] = 1;
        }
        if (!flag) {
            printf("YES\n");
            return 0;
        }
    }
    printf("NO\n");
    return 0;
}

赛后补题


C - Berzerk

Problem Description

ns使s[i][j]使

Data Limit

n<=7000

Solution

f[i][j]ijf[i][j]
f[(i+s[k][j])][! j]

Code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 7005;
int s[N][2], f[N][2], n, k[2];
int vis[N][2];
inline int work(int pos, int fir) {
    if (vis[pos][fir] || f[pos][fir]) return f[pos][fir];
    vis[pos][fir] = 1;
    int nxt, val;
    for (int i = 1; i <= k[fir]; i ++) {
        nxt = (pos + s[i][fir]) % n;
        if (!nxt) nxt = n;
        if (nxt == 1) {
            f[pos][fir] = 1;
            return 1;
        }
    }
    int cnt = 0;
    for (int i = 1; i <= k[fir]; i ++) {
        nxt = (pos + s[i][fir]) % n;
        val = work(nxt, 1 - fir);
        if (val == -1) {
            f[pos][fir] = 1;
            return 1;
        }
        else if(val == 1) cnt ++;
    }
    if (cnt == k[fir]) f[pos][fir] = -1;
    return f[pos][fir];
}
int main() {
    scanf("%d", &n);
    for (int j = 0; j <= 1;j ++) {
        scanf("%d", &k[j]);
        for (int i = 1; i <= k[j]; i ++) scanf("%d", &s[i][j]);
    }
    for (int j = 0; j <= 1; j ++) {
        memset(vis, 0, sizeof(vis));
        for (int i = n; i >= 1; i --) {
            work(i, 0);
            work(i, 1);
        }
    }
    for(int j = 0; j <= 1; j ++) {
        for(int i = 2; i <= n; i ++) {
            if (f[i][j] == -1) printf("Lose ");
            else if (f[i][j] == 0) printf("Loop ");
            else printf("Win ");
        }
        printf("\n");
    }
    return 0;
}

D - Legacy

Problem Description

u>vu>[l,r][l,r]>u

Data Limit

1n,q105, 1sn

Solution

线
Alt text
O(log(q))

Code

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 100005;
struct node{int nxt, to, w;} edge[3100000];
int que[N], cnt = 0, tot;
int fir[N * 8], back[N * 8];
LL dis[N * 8];
bool inq[N * 8];
inline void add(int x, int y, int l) {
    edge[++ cnt].to = y;
    edge[cnt].nxt = fir[x];
    edge[cnt].w = l;
    fir[x] = cnt;
}
inline void build(int x, int l, int r) {
    if (l == r) {
        back[l] = x;
        add(x, x + N * 4, 0);
        add(x + N * 4, x, 0);
        return;
    }
    int mid = (l + r) >> 1, lc = x << 1, rc = lc + 1;
    build(lc, l, mid);
    build(rc, mid + 1, r);
    add(x, lc, 0);
    add(x, rc, 0);
    add(lc + N * 4, x + N * 4, 0);
    add(rc + N * 4, x + N * 4, 0);
}
inline void Query(int x, int l, int r, int a, int b) {
    if (l == a && r == b) {
        que[++ tot] = x;
        return;
    }
    int mid = (l + r) >> 1;
    if (b <= mid) Query(x << 1, l, mid, a, b);
    else if (a > mid) Query(x << 1 | 1, mid + 1, r, a, b);
    else Query(x << 1, l, mid , a, mid), Query(x << 1 | 1, mid + 1, r, mid + 1, b);
}
int main() {
    int n, q, s, opt, v, l, r, u, w;
    scanf("%d%d%d", &n, &q, &s);
    build(1, 1, n);
    while (q --) {
        scanf("%d", &opt);
        if (opt == 1) {
            scanf("%d%d%d", &u, &v, &w);
            add(back[u], back[v], w);
        } else {
            scanf("%d%d%d%d", &v, &l, &r, &w);
            tot = 0;
            Query(1, 1, n, l, r);
            if (opt == 2) {
                for (int i = 1; i <= tot; i ++) add(back[v], que[i], w);
            } else {
                for (int i = 1; i <= tot; i ++) add(que[i] + N * 4, back[v], w);
            }
        }
    }
    memset(dis, 127, sizeof(dis));
    LL un = dis[0];
    queue<int> Q;
    Q.push(back[s]);
    dis[back[s]] = 0;
    while (!Q.empty()) {
        int x = Q.front();
        Q.pop();
        inq[x] = 0;
        for (int i = fir[x]; i; i = edge[i].nxt) {
            v = edge[i].to;
            if(dis[v] > dis[x] + (LL)edge[i].w) {
                dis[v] = dis[x] + (LL)edge[i].w;
                if (!inq[v]) {
                    inq[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
    for (int i = 1; i <= n; i ++) {
        if(dis[back[i]] != un) printf("%I64d ", dis[back[i]]);
        else printf("-1 ");
    }
    printf("\n");
    return 0;
}

E - Till I Collapse

Problem Description

k[1,n]使k

Data Limit

n105

Solution

[l,r]
ans[l]==ans[r]ans

Code

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100005;
int ans[N], col[N], tab[N], n;
inline int count(int x) {
    memset(tab, 0, sizeof(tab));
    int ret = 1, cnt = 0;
    for (int i = 1; i <= n; i ++) {
        if (tab[col[i]] == ret) continue;
        tab[col[i]] = ret;
        cnt ++;
        if (cnt > x) {
            cnt = 1;
            tab[col[i]] = ++ ret;
        }
    }
    return ret;
}
inline void work(int l, int r) {
    if (l > r) return;
    int cl = count(l);
    if (l == r) {
        ans[l] = cl;
        return;
    }
    int cr = count(r);
    if (cl == cr) {
        for (int i = l; i <= r; i ++) ans[i] = cl;
        return;
    }
    ans[l] = cl;
    ans[r] = cr;
    int mid = (l + r) >> 1;
    work(l + 1, mid);
    work(mid + 1, r - 1);
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++) scanf("%d", &col[i]);
    work(1, n);
    for (int i = 1; i <= n; i ++) printf("%d ",ans[i]);
    printf("\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值