Codeforces Round #548 (Div. 2)

Posted hjmmm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #548 (Div. 2)相关的知识,希望对你有一定的参考价值。

比赛链接
cf

A

最后一位判定

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#define P(x, y) 1ll * (x) * inv(y) % P
using namespace std;
typedef long long ll;
const int N = 65005;
const ll P = 1e9 + 7;
int n;
ll ans;
char str[N];
int main(){
    scanf("%d%s", &n, str + 1);
    for(int i = 1; i <= n; ++i){
        if(!((str[i] - '0') & 1)) ans += i;
    }
    printf("%lld", ans);
    return 0;
}

B

倒叙维护最大值

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#define P(x, y) 1ll * (x) * inv(y) % P
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
const ll P = 1e9 + 7;
int n, a[N], lim;
ll ans;
int main(){
    scanf("%d", &n);
    for(int i = 1, x; i <= n; ++i){
        scanf("%d", &a[i]);
    }
    lim = a[n]; ans += a[n];
    for(int i = n - 1; i >= 1; --i){
        lim = max(0, min(lim - 1, a[i]));
        ans += lim;
    } 
    printf("%lld\n", ans);
    return 0;
}

C

所有方案 - 全是红边的方案
并查集维护

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 5;
const ll P = 1e9 + 7;
int n, m; ll ans;
int size[N], fa[N];
inline ll qpow(ll x, ll y){
    ll res = 1;
    while(y){
        if(y & 1) res = res * x % P;
        x = x * x % P; y >>= 1;
    }
    return res;
}
int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
inline void merge(int x, int y){x = find(x), y = find(y), fa[x] = y, size[y] += size[x];}
int main(){
    scanf("%d%d", &n, &m);
    ans = qpow(n, m);
    for(int i = 1; i <= n; ++i) fa[i] = i, size[i] = 1;
    for(int i = 1, x, y, z; i < n; ++i){
        scanf("%d%d%d", &x, &y, &z);
        if(!z) merge(x, y);
    }
    for(int i = 1; i <= n; ++i){
        if(fa[i] == i){
            ans = (ans + P - qpow(size[i], m)) % P;
        }
    }
    printf("%lld\n", ans); 
    return 0;
}

然后我就自闭了?

D

给定数m \(m \leq 1e5\)
进行如下流程:
1.rand一个[1, m]的数
2.把它接在序列a后面
3.如果a的gcd等于1 退出 否则进行第一步
求进行流程次数的期望

前面那个\(\frac{(m-m/x)}{m}\)是抽到的数不是自己的倍数的概率
\(\frac{(m-m/x)}{m}*dp[x] = 1 + \sum_{d|x}^{m} \frac{dp[d]*c[d]}{m}\)
当然容斥那里用莫比乌斯函数也ok啦【因为懒所以这么写了

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 5;
const ll P = 1e9 + 7;
inline ll qpow(ll x, ll y){
    ll res = 1;
    while(y){
        if(y & 1) res = res * x % P;
        x = x * x % P; y >>= 1;
    }
    return res;
}
int cnt[N], m, invm;
vector<int> d[N];
ll f[N];
inline void init(){
    for(int i = (m >> 1); i > 1; --i)
        for(int j = (i << 1); j <= m; j += i)
            d[j].push_back(i);
    invm = qpow(m, P - 2);
}
inline void cut(int x){
    for(int i : d[x]) cnt[i] -= cnt[x];
}
int main(){
    scanf("%d", &m), init();
    for(int i = 2; i <= m; ++i){
        for(int j : d[i]) cnt[j] = m / j;
        cnt[i] = m / i, cut(i);
        for(int j : d[i]){
            f[i] = (f[i] + f[j] * cnt[j] % P) % P;
            cut(j);
        }
        f[i] = ((f[i] + 1ll * m) % P * qpow(m - m / i, P - 2) % P) % P;
    }
    ll ans = 0;
    for(int i = 2; i <= m; ++i) ans = (ans + f[i]) % P;
    ans = (ans * invm % P + 1) % P;
    printf("%lld", ans);
    return 0;
}

E

有n个点 m个集合
每个点有一个权值pi 有一个集合编号ci
每次删掉一个点之后查询每个集合选一个权值的最大mex
所有数据小于等于5000

倒着加边 边加边匹配

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
#define mp(x, y) make_pair(x, y)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 5005;
int n, m;
struct Edge{int v, next;}edge[N];
int head[N], esize;
inline void addedge(int x, int y){
    edge[++esize] = (Edge){y, head[x]}, head[x] = esize;
}
int p[N], c[N], day[N], ans;
int d, bk[N], match[N];
bool vis[N], del[N];
bool dfs(int x){
    for(int i = head[x], vv; ~i; i = edge[i].next){
        vv = edge[i].v;
        if(!vis[vv]){
            vis[vv] = 1;
            if(!match[vv] || dfs(match[vv])){
                match[vv] = x; return 1;
            }
        }
    }
    return 0;
}
int main(){
    memset(head, -1, sizeof(head));
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) scanf("%d", &p[i]), ++p[i];
    for(int i = 1; i <= n; ++i) scanf("%d", &c[i]);
    scanf("%d", &d);
    for(int i = 1; i <= d; ++i) scanf("%d", &bk[i]), del[bk[i]] = 1;
    ans = 1;
    for(int i = 1; i <= n; ++i) if(!del[i]) addedge(p[i], c[i]);
    for(int i = d; i >= 1; --i){ 
        memset(vis, 0, sizeof(vis));
        while(dfs(ans)){++ans; memset(vis, 0, sizeof(vis));} 
        day[i] = ans - 1;
        addedge(p[bk[i]], c[bk[i]]);
    } 
    for(int i = 1; i <= d; ++i) printf("%d\n", day[i]);
    return 0;
}

F

太神仙了慢慢搞
一眼扫描线?

以上是关于Codeforces Round #548 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

C. Edgy Trees Codeforces Round #548 (Div. 2) 并查集求连通块

Codeforces Round #548 (Div. 2) C dp or 排列组合

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

codeforces #548 div2

loj548 「LibreOJ β Round #7」某少女附中的体育课