同样一分代码,加了注释A了
TLE代码:(有反作弊
#include <bits/stdc++.h>
#define INF 99999999
using namespace std;
int n,k,p,q,l,a[1000020],vis[1000020],c[1000020],c1[1000020],f[1000020],book[1000020],d[1000020],e[1000020];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int dfs(int s,int now,int cnt)
{
vis[now]=1;
if(s==now&&cnt!=1)return cnt-1;
else dfs(s,a[now],cnt+1);
}
void least()
{
for(int i=1;i<=p;i++)
if(!book[c[i]])d[++l]=c[i],book[c[i]]=1,e[c[i]]++;
else e[c[i]]++;
for(int i=1;i<=l;i++)
{
int now=0;
for(int j=1;now<=e[d[i]];j*=2)
if(now+j<=e[d[i]])c1[++q]=d[i]*j,now+=j;
else break;
if(e[d[i]]>now)c1[++q]=(e[d[i]]-now)*d[i];
}
for(int i=1;i<=k;i++)f[i]=-INF;
for(int i=1;i<=q;i++)
for(int j=k;j>=c1[i];j--)
f[j]=max(f[j],f[j-c1[i]]+c1[i]);
if(f[k]>=0)printf("%d ",k);
else printf("%d ",k+1);
}
void most()
{
int h=0,cnt=0;
bool flag=0;
for(int i=1;i<=p;i++)
{
if(h+c[i]/2<=k)h+=c[i]/2;
else
{
h=k;
flag=1;
}
if(c[i]%2)cnt++;
}
h*=2;
if(flag==0)h+=min(k-h/2,cnt);
printf("%d",h);
}
int main()
{
n=read();k=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)
if(!vis[i])c[++p]=dfs(i,i,1);
least();
most();
return 0;
}
AC代码:(有反作弊(未开O2
#include <bits/stdc++.h>
#define INF 99999999
using namespace std;
//O2...
int n,k,p,q,l,a[1000020],vis[1000020],c[1000020],c1[1000020],f[1000020],book[1000020],d[1000020],e[1000020];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int dfs(int s,int now,int cnt)
{
vis[now]=1;
if(s==now&&cnt!=1)return cnt-1;
else dfs(s,a[now],cnt+1);
}
void least()
{
for(int i=1;i<=p;i++)
if(!book[c[i]])d[++l]=c[i],book[c[i]]=1,e[c[i]]++;
else e[c[i]]++;
for(int i=1;i<=l;i++)
{
int now=0;
for(int j=1;now<=e[d[i]];j*=2)
if(now+j<=e[d[i]])c1[++q]=d[i]*j,now+=j;
else break;
if(e[d[i]]>now)c1[++q]=(e[d[i]]-now)*d[i];
}
for(int i=1;i<=k;i++)f[i]=-INF;
for(int i=1;i<=q;i++)
for(int j=k;j>=c1[i];j--)
f[j]=max(f[j],f[j-c1[i]]+c1[i]);
if(f[k]>=0)printf("%d ",k);
else printf("%d ",k+1);
}
void most()
{
int h=0,cnt=0;
bool flag=0;
for(int i=1;i<=p;i++)
{
if(h+c[i]/2<=k)h+=c[i]/2;
else
{
h=k;
flag=1;
}
if(c[i]%2)cnt++;
}
h*=2;
if(flag==0)h+=min(k-h/2,cnt);
printf("%d",h);
}
int main()
{
n=read();k=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)
if(!vis[i])c[++p]=dfs(i,i,1);
least();
most();
return 0;
}
所以加了一行注释竟然过了