zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 097 D

     链接https://atcoder.jp/contests/arc097/tasks/arc097_b

    题意 给你一个排列

    然后给你M个pair,这两个pair位置的值可以互换,

    然后问你最多能换成多少个位置的pi=i;

    题解:

    手玩了一下,发现你连起来的pair,可以互换成全排列,

    然后这就是个并查集的问题了,

    合并他们能到达的位置的集合,

    每次查询当前并查集里的位置能不能达到就可以了

    然后学了一下合并两个vector的函数

    #include<bits/stdc++.h>
    //#include<tr1::unordered_map>
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,a,n) for(int i=n;i>=a;--i)
    #define pb push_back
    #define fi first
    #define se second
    #define io std::ios::sync_with_stdio(false)
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    const int  maxn=1e5+10;
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll qpow(ll a,ll n)
    {
        ll r=1%P;
        for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;
        return r;
    }
    int fa[maxn];
    vector<int> ans[maxn];
    int a[maxn];
    int findfa(int x)
    {
    
        if(fa[x]==x)
            return x;
        else
            return fa[x]=findfa(fa[x]);
    }
    int main()
    {
      io;
      int n,m;
      cin>>n>>m;
      for(int i=1;i<=n;i++)
      {cin>>a[i];
      fa[i]=i;
      ans[i].push_back(i);//肯定能到达自己,方便合并
      }
      while(m--)
      {
    
          int x,y;
          cin>>x>>y;
          int t=findfa(x);
          int tt=findfa(y);
          if(t==tt) continue;
          if(ans[t].size()>ans[tt].size())
          {
              ans[t].insert(ans[t].end(),ans[tt].begin(),ans[tt].end());//合并操作
              fa[tt]=t;
              ans[tt].clear();
          }
          else
          {
              ans[tt].insert(ans[tt].end(),ans[t].begin(),ans[t].end());
              fa[t]=tt;
              ans[t].clear();
          }
      }
      int sum=0;
      for(int i=1;i<=n;i++) sort(ans[i].begin(),ans[i].end());
      for(int i=1;i<=n;i++)
      {
    
          if(a[i]==i)
          {  
              sum++; continue;
    
          }
          int f=findfa(i);
          int id=lower_bound(ans[f].begin(),ans[f].end(),a[i])-ans[f].begin();
          if(id<ans[f].size()&&ans[f][id]==a[i])
          {
              sum++;
             
          }
      }
      cout<<sum<<endl;
    }
  • 相关阅读:
    操作系统学习笔记:银行家算法的回顾和训练
    操作系统学习笔记:内存学习随笔
    操作系统笔记:内存的连续管理
    操作系统笔记:内存的离散管理
    操作系统:内存管理复习ing之页面置换算法
    马原学习日记1:实践
    bootstrap简单教程
    css-6(媒体识别)
    css-5(弹性盒子)
    css-3(旋转+过渡)
  • 原文地址:https://www.cnblogs.com/acmLLF/p/13642314.html
Copyright © 2011-2022 走看看