Codeforces Global Round 20 D F1 F2/more

https://codeforc.es/contest/1672

F1

https://www.luogu.com.cn/blog/AlexWei/solution-cf1672f1

  1. 将置换分解为若干轮换(环),悲伤值越大 环越少(设环为 k 个,一个环只需要交换 sz1 次,所以总共交换 nk 次,显然环越少,悲伤值越大)

  2. 根据其置换的最优性,2 个相同的元素不可能同时出现在一个环。
    考虑 p1p2...pipi+1...pjpj+1...p1,其中 pipj 的权值相等。显然可以拆成 2 个环,p1p2...pipj+1p1pi+1...pjpi+1 这一部分是因为你交换 2 个数要交换到哪里,由于这两个元素一样,所以并不会影响正确性。由于环更多了,显然会成这样。得证。

  3. 根据 2,显然环的下界个数是 mx 个,mx 为众数出现次数。

于是把众数的元素分到每一个环即可。

#include <bits/stdc++.h> //#define int long long #define pb push_back using namespace std; const int N=(int)(2e5+5); //pair<int,int>vec[N]; map<int,vector<int> >mp; int n,a[N],ct[N],vec[N]; void sol() { mp.clear(); cin>>n; int mx=0,mxv=0; for(int i=1;i<=n;i++) { cin>>a[i]; ++ct[a[i]]; if(ct[a[i]]>mxv) mx=a[i],mxv=ct[a[i]]; } for(int i=1;i<=n;i++) { // if(a[i]!=mx) { mp[a[i]].pb(i); // } } for(int i=0;i<mxv;i++) { int tot=0; vec[++tot]=mp[mx][i]; for(auto it=mp.begin();it!=mp.end();) { // cout<<i<<'\n'; if((*it).first==mx) { ++it; continue ; } vec[++tot]=(*it).second.back(); (*it).second.pop_back(); if((*it).second.empty()) { mp.erase(it++); } else ++it; } int qwq=a[vec[tot]]; for(int j=tot-1;j>=1;j--) { a[vec[j+1]]=a[vec[j]]; } a[vec[1]]=qwq; } for(int i=1;i<=n;i++) ct[a[i]]=0; for(int i=1;i<=n;i++) cout<<a[i]<<' '; cout<<'\n'; } signed main() { cin.tie(0); ios::sync_with_stdio(false); int T; cin>>T; while(T--) sol(); return 0; }

F2

image

#include <bits/stdc++.h> //#define int long long #define pb push_back using namespace std; const int N=(int)(4e5+5); bool vis[N]; int n,a[N],b[N],dfn[N],low[N],ct[N],fir[N],tjtot; bool ok; vector<int>st,vec[N],g[N]; void tarjan(int x) { dfn[x]=low[x]=++tjtot; vis[x]=1; st.pb(x); for(int y:g[x]) { if(!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); } else if(vis[y]) low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { int qwq=0,sz=0; while(1) { qwq=st.back(); st.pop_back(); ++sz; vis[qwq]=0; if(qwq==x) break ; } if(sz>1) { ok=0; return ; } } } void sol() { cin>>n; tjtot=0; ok=1; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) cin>>b[i]; int mxv=0,mx=0; for(int i=1;i<=n;i++) { ++ct[b[i]]; if(ct[b[i]]>mxv) mxv=ct[b[i]],mx=b[i]; } for(int i=1;i<=n;i++) vec[a[i]].pb(i); int tot=n; for(int i=1;i<=n;i++) { if(b[i]==mx) continue ; if(fir[b[i]]) { g[i].pb(fir[b[i]]); continue ; } fir[b[i]]=++tot; g[i].pb(fir[b[i]]); for(int x:vec[b[i]]) g[fir[b[i]]].pb(x); } for(int i=1;i<=tot;i++) { if(!dfn[i]) { while(!st.empty()) st.pop_back(); tarjan(i); } } for(int i=1;i<=n;i++) ct[b[i]]=fir[b[i]]=0,vec[a[i]].clear(); for(int i=1;i<=tot;i++) g[i].clear(),low[i]=dfn[i]=vis[i]=0; if(ok) { cout<<"AC\n"; } else cout<<"WA\n"; } signed main() { cin.tie(0); ios::sync_with_stdio(false); int T; cin>>T; while(T--) sol(); return 0; }

D

image

很奇妙的题目,比 F 难多了!


__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/16855961.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示