貌似叫置换群?
这位叫novosbirsk的神犇讲的太好了,我也没法补充什么qaq。。。
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=10005;
int n,tot,ans,a1,a2,mi=100005;
int tar[N],num[N];
int angry[N];
bool vis[N];
struct lyf{
int le;
int sum;
int mi;
}qu[N];
inline void read(int &x)
{
int f=1;
x=0;
char ch=getchar();
while (ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
x*=f;
}
inline int sear(int x)
{
int l=1,r=n,mid;
while (l<r)
{
mid=(l+r)>>1;
if(tar[mid]==x) return mid;
if(tar[mid]>x) r=mid-1;
else l=mid+1;
}
return l;
}
inline void rush(int x)
{
vis[x]=1;
qu[++tot].le=1;
qu[tot].sum+=angry[x];
qu[tot].mi=angry[x];
int wz=num[x];
while (wz!=x)
{
qu[tot].le++;qu[tot].sum+=angry[wz];
qu[tot].mi=min(qu[tot].mi,angry[wz]);
vis[wz]=1;
wz=num[wz];
}
return ;
}
int main()
{
register int i;
read(n);
for (i=1;i<=n;i++)
{
read(angry[i]);
tar[i]=angry[i];
mi=min(mi,tar[i]);
}
sort(tar+1,tar+1+n);
for (i=1;i<=n;i++)
{
num[i]=sear(angry[i]);
}
for (i=1;i<=n;i++)
{
if (!vis[i]&&num[i]!=i)
{
rush(i);
}
}
for (i=1;i<=tot;i++)
{
a1=(qu[i].le-2)*qu[i].mi;
a2=(qu[i].le+1)*mi+qu[i].mi;
ans+=qu[i].sum+min(a1,a2);
}
printf("%d",ans);
return 0;
}