Codeforces Round 747 div.2 A-E

本文最后更新于:2 年前

A. Consecutive Sum Riddle

题意:给定一个 $n$,要找出 $l,r$ 使得 $\sum_{i=l}^{r}i=n$

解:显然,从 $-n+1$ 加到 $n$ 即可

void solve(){
    ll n;
    cin >> n;
    cout << -n+1 << ' ' << n << '\n';
}

B. Special Numbers

题意:找第 $k$ 个 $n$ 好数,$n$ 好数就是可以被 $n$ 的不同次幂组成,比如 $n^0+n^2…$ 的方式表示

解:把 $k$ 转化为二进制,然后每一位按照 $n$ 的次幂加权计算即可

void solve(){
    ll n, k;
    cin >> n >> k;
    ll ans = 0, t = 1;
    while(k > 0){
        if(k & 1){
            ans = (ans + t) % mode;
        }
        k >>= 1;
        t = t * n % mode;
    }
    cout << ans << '\n';
}

C. Make Them Equal

题意:给出一个字符串 $s$ 和字符 $c$,可以进行若干次操作,每次操作可以选择一个数 $x$,然后令字符串中所有下标不能被 $x$ 的整除的位置上的字符变成 $c$,问最少多少次操作可以使字符串全变成 $c$

解:由于 $n>2$,两次操作分别选择 $n$ 和 $n-1$ 一定可以完成,那么只需要考虑能不能一次完成

一次完成要求存在一个数 $x$,串中所有可以被 $x$ 整除的位置上都已经是 $c$ 了,暴力枚举即可,复杂度比较玄学但它就是 $nlogn$

后来又听了无敌的会长的优化方案:只需要枚举 $n/2$ 以上的 $x$ 即可,因为更小的 $x$ 总有一个倍数比它更优,复杂度 $2n$

void solve(){
    int n;
    char c;
    string s;
    cin >> n >> c >> s;
    s = "0" + s;
    for(int i=1;i<=n;i++){
        bool flg = true;
        for(int j=i;j<=n;j+=i){
            if(s[j] != c){
                flg = false;
                break;
            }
        }
        if(flg){
            if(i == 1){
                cout << "0\n";
                return;
            }
            cout << 1 << '\n';
            cout << i << '\n';
            return;
        }
    }
    cout << 2 << '\n';
    cout << n-1 << ' ' << n << '\n';
}

D. The Number of Imposters

题意:有 $n$ 个人和 $m$ 个陈述,每个陈述形如:$i,j,imposter/crewmate$ 表示 $i$ 说 $j$ 是说真话的人/说谎者,问说谎话的人最多有几个

解:注意到一个性质:如果 $i$ 说 $j$ 说的是谎话,那么 $i$ 和 $j$ 必定相反;如果 $i$ 说 $j$ 说的是真话,那么 $i$ 和 $j$ 相同。

那么每个陈述都可以转化为一条边,对每个联通块进行染色后取较多的颜色加入贡献即可

int st[maxn];
struct Edge{
    int t, nt, tp;
}e[maxn << 1];
int head[maxn], ecnt = 0;

inline void add(int x, int y, int tp){
    e[++ecnt].t = y;
    e[ecnt].tp = tp;
    e[ecnt].nt = head[x];
    head[x] = ecnt;
}

int num[2];
bool dfs(int p){
    for(int i=head[p];i;i=e[i].nt){
        int v = e[i].t;
        if(st[v] == -1){
            st[v] = st[p] ^ e[i].tp;
            num[st[v]]++;
            if(!dfs(v)) return false;
        }else{
            if(st[v] != (st[p] ^ e[i].tp)) return false;
        }
    }
    return true;
}

void solve(){
    int n, m;
    cin >> n >> m;

    ecnt = 0;
    for(int i=1;i<=n;i++){
        head[i] = 0;
        st[i] = -1;
    }

    for(int i=1;i<=m;i++){
        int x, y; string s;
        cin >> x >> y >> s;
        int tp = (s[0] == 'i');
        add(x, y, tp);
        add(y, x, tp);
    }
    int ans = 0;
    for(int i=1;i<=n;i++){
        if(st[i] == -1){
            st[i] = 1;
            num[1] = 1;
            num[0] = 0;
            if(!dfs(i)){
                cout << "-1\n";
                return;
            }
            ans += max(num[0], num[1]);
        }
    }
    cout << ans << '\n';
}

E1. Rubik’s Cube Coloring (easy version)

题意:给一颗 $k$ 层的完全二叉树,每个节点有一个颜色(共六种),要求每个节点和其相邻节点颜色不能相同,并且规定了三对不能相邻的颜色,问有多少中染色方案

解:答案为 $4^{2^n-2}\times 6$

ll qpow(ll x, ll p){
    ll r = 1;
    while(p > 0){
        if(p & 1) r = r * x % mode;
        x = x * x % mode;
        p >>= 1;
    }
    return r;
}

void solve(){
    int n;
    cin >> n;
    cout << qpow(4, (1ll << n) - 2) * 6 % mode << '\n';
}

Codeforces Round 747 div.2 A-E
http://www.lxtyin.ac.cn/2021/10/09/2021-10-09-Codeforces Round 747 div.2/
作者
lx_tyin
发布于
2021年10月9日
许可协议