zoukankan      html  css  js  c++  java
  • Atcoder D

    题目链接:http://agc016.contest.atcoder.jp/tasks/agc016_d

    题解:稍微想一下就知道除了第一次的x是所有的异或值,之后的x都是原先被替换掉的a[i]所以要想可以通过操作得到必须使a[i]里的所有数b[j]里都有

    而且数量相同,(a[0]=a[1]^a[2]^..^a[n],b[0]=b[1]^b[2]^..^b[n])。然后就是怎么交换能够使得操作数最少,其实可以用并查集,但是用dfs比较好理解

    一点其实都是一样的。显然f[a[i]]=b[i],于是如果a[i]!=b[i]就可以把a[i]-b[i]连起来然后dfs一遍肯定能在a[i]结束。最后找一下规律就行。注意i=0链接

    时候的贡献是不需要的。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int M = 1e5 + 10;
    int a[M] , b[M] , ha[M] , hb[M];
    bool vis[M] , have[M];
    vector<int>vc[M];
    void dfs(int u) {
        vis[u] = true;
        int len = vc[u].size();
        for(int i = 0 ; i < len ; i++) {
            int v = vc[u][i];
            if(vis[v]) continue;
            dfs(v);
        }
    }
    int main() {
        int n;
        cin >> n;
        a[0] = 0;
        for(int i = 1 ; i <= n ; i++) {
            cin >> a[i];
            a[0] ^= a[i];
            ha[i] = a[i];
        }
        ha[0] = a[0];
        b[0] = 0;
        for(int i = 1 ; i <= n ; i++) {
            cin >> b[i];
            b[0] ^= b[i];
            hb[i] = b[i];
        }
        hb[0] = b[0];
        sort(ha , ha + n + 1);
        sort(hb , hb + n + 1);
        for(int i = 0 ; i <= n ; i++) {
            if(ha[i] != hb[i]) {
                cout << -1 << endl;
                return 0;
            }//这里是判断能否通过操作得到。
        }
        for(int i = 0 ; i <= n ; i++) {
            a[i] = lower_bound(ha , ha + 1 + n , a[i]) - ha;
            b[i] = lower_bound(hb , hb + 1 + n , b[i]) - hb;
        }//离散一下由于a[i],b[i]太大了。当然用map就不用这样操作了。
        int ans = 0;
        memset(have , false , sizeof(have));
        memset(vis , false , sizeof(vis));
        for(int i = 0 ; i <= n ; i++) {
            if(a[i] != b[i] || i == 0) {
                if(i) ans++;
                have[a[i]] = true , have[b[i]] = true;
                vc[a[i]].push_back(b[i]);
            }
        }
        for(int i = 0 ; i <= n ; i++) {
            if(!vis[i] && have[i]) {
                dfs(i) , ans++;
            }
        }
        ans--;//这里的ans--是减去第0位点被算进去的情况
        ans = max(ans , 0);
        cout << ans << endl;
        return 0;
    }
    
    
  • 相关阅读:
    [codevs 1243][网络提速(最短路分层思想)
    [codevs 1183][泥泞的道路(二分+spfa)
    [codevs 2488]绿豆蛙的归宿(拓扑排序)
    [codevs 1961]躲避大龙(dfs)
    4、userCF和itemCF对比,冷启动
    query简洁弹出层代码
    css 积累1
    localStorage,sessionStorage
    tr th td
    (转存)面向切面编程(AOP)的理解
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7064739.html
Copyright © 2011-2022 走看看