code

#include<bits/stdc++.h>
typedef int LL;
const LL mod=1e9+7,maxn=1e6+9,inf=1e9;
void Chkmin(LL &x,LL y){
	if(y<x) x=y;
}
LL mul(LL x,LL y){
	return 1ll*x*y%mod;
}
LL Pow(LL base,LL b){
	LL ret(1); while(b){
		if(b&1) ret=mul(ret,base);
		base=mul(base,base); b>>=1;
	}return ret;
}
LL T,n;
LL p[maxn],cnt[10],vis[maxn];
LL Query(LL c1,LL c2){
	if(c2>=c1){
		return c1+(c2-c1);
	}
	return c2+(c1-c2)/3*2;
}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(LL i=1;i<=n;++i) scanf("%d",p+i);
		for(LL i=1;i<=n;++i) vis[i]=0;
		LL ans(0);
		memset(cnt,0,sizeof(cnt));
		for(LL i=1;i<=n;++i) if(!vis[i]){
			LL x(i),len(0);
			while(!vis[x]){
				vis[x]=1;
				x=p[x];
				++len;
			}
			if(len==1){
				cnt[1]++;
			}else if(len%3==0){
			    ans+=len/3-1; cnt[3]++;
			}else if(len%3==2){
				ans+=len/3; cnt[2]++;
			}else{
				ans+=len/3-1; cnt[4]++;
			}
		}
		if(n==1){
			puts("1 0");
			continue;
		}
		if(n==4){
			printf("4 ");
			if(cnt[3]){
				printf("1\n");
			}else if(cnt[4]){
				printf("0\n");
			}else if(cnt[2]==2){
				printf("0\n");
			}else if(cnt[2]==1 && cnt[1]==2){
				printf("1\n");
			}else{
				puts("2");
			}
			continue;
		}
		if(n%3==0){
			printf("%d ",Pow(3,n/3));
			ans+=cnt[4];
			cnt[1]+=cnt[4];
			ans+=Query(cnt[1],cnt[2]);
		}else if(n%3==2){
			printf("%d ",mul(2,Pow(3,n/3)));
			ans+=cnt[4];
			cnt[1]+=cnt[4];
			LL ret1(inf),ret2(inf);
			if(cnt[1]>=2){
				ret1=1+Query(cnt[1]-1,cnt[2]);
			}
			if(cnt[2]>=1){
				ret2=Query(cnt[1],cnt[2]-1);
			}
			ans+=std::min(ret1,ret2);
		}else{
			printf("%d ",mul(4,Pow(3,n/3-1)));
			LL ret1(inf),ret2(inf),ret3(inf),ret4(inf);
			if(cnt[4]){
				ret1=cnt[4]-1+Query(cnt[1]+cnt[4]-1,cnt[2]);
				Chkmin(ret1,cnt[4]+Query(cnt[1]+cnt[4]-1,cnt[2]));
			}
			if(cnt[3] && cnt[1]){
				ret2=cnt[4]+1+Query(cnt[1]-1+cnt[4],cnt[2]);
			}
			if(cnt[2]>=2){
				ret3=cnt[4]+Query(cnt[1]+cnt[4],cnt[2]-2);
			}
			if(cnt[2]>=1 && cnt[1]>=2){
				Chkmin(ret3,1+cnt[4]+Query(cnt[1]-2+cnt[4],cnt[2]-1));
			}
			if(cnt[1]>=4){
				ret4=2+cnt[4]+Query(cnt[1]-4+cnt[4],cnt[2]);
			}
			LL ret(ret1);
			Chkmin(ret,ret2);
			Chkmin(ret,ret3);
			Chkmin(ret,ret4);
			ans+=ret;
		}
		printf("%d\n",ans);
		//exit(0);
	}
}
posted @ 2020-12-22 11:17  Grice  阅读(162)  评论(0编辑  收藏  举报