AtCoder Regular Contest 151

A. Equal Hamming Distances

简单题,注意下答案需要字典序最小即可


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define ll long long

signed main()
{
    int n;
    string a, b;
    cin >> n >> a >> b;
    int cnt(0);
    rep(i, 0, n - 1) if (a[i] != b[i]) cnt++;
    if (cnt % 2) cout << -1 << endl;
    else
    {
        string ans(a);
        int s1 = 0, s2 = 0; cnt /= 2;
        rep(i, 0, n - 1)
        {
            if (a[i] != b[i])
            {
                if (a[i] == '0')
                {
                    if (s1 < cnt) s1++;
                    else
                    {
                        ans[i] = b[i];
                        s2++;
                    }
                }
                else
                {
                    if (s2 < cnt)
                    {
                        s2++;
                        ans[i] = b[i];
                    }
                    else s1++;
                }
            }
            else ans[i] = '0';
        }
        cout << ans << endl;
    }
}

B. A < AP

知识点:计数,连通块
复杂度:\(O(n)\)

一开始被题目吓住了,以为要上带权并查集,后来发现只需要维护连通块的个数即可

枚举 \(A\) 中第一个满足 \(A_i<A_{P_i}\) 的位置
那么对所有的 \(1\)\(i-1\) 都要满足 \(A_i=A_{P_i}\)
我们将之前的 \(j\)\(p_j\) 使用并查集合并
那么此时符合题意的数列个数为 \(C_m^2×m^{cnt-2}\)
\(cnt\) 为连通块个数

注意 \(i\)\(p_i\) 可能一开始就连通,所以要用并查集维护


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,l,r) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define endl '\n'
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;

const int mod = 998244353;
const int N = 2e5 + 5;

int f[N];
void init(int n) { iota(f, f + n + 1, 0); }
int find(int u)
{
    if (f[u] == u) return u;
    return f[u] = find(f[u]);
}
bool link(int u, int v)
{
    int fu = find(u), fv = find(v);
    if (fu == fv) return false;
    f[fu] = fv;
    return true;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    ll n, m;
    cin >> n >> m;
    init(n);
    vc<ll> p(n + 1), pow_m(n + 1);
    pow_m[0] = 1;
    rep(i, 1, n)
    {
        cin >> p[i];
        pow_m[i] = pow_m[i - 1] * m % mod;
    }
    ll cm2 = m * (m - 1) / 2 % mod;
    int cnt = n;
    ll ans = 0;
    for (int t = 1; t <= n; t++) if (link(t, p[t]))
    {
        ans = (ans + cm2 * pow_m[cnt - 2]) % mod;
        cnt--;
    }
    cout << ans << endl;
}

原文地址:http://www.cnblogs.com/lunasama/p/16901800.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性