QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#447348#6954. Almost Acyclickkkgjyismine4AC ✓1978ms17948kbC++143.9kb2024-06-18 10:28:522024-06-18 10:28:53

Judging History

你现在查看的是最新测评结果

  • [2024-06-18 10:28:53]
  • 评测
  • 测评结果:AC
  • 用时:1978ms
  • 内存:17948kb
  • [2024-06-18 10:28:52]
  • 提交

answer

#include<bits/stdc++.h>
#define i28 __int128
using namespace std;
const int mod=1e9+7;
int mul(int x,int y){return 1ll*x*y%mod;}
void add(int &x,const int y){if((x+=y)>=mod)x-=mod;}
void sub(int &x,const int y){if((x+=(mod-y))>=mod)x-=mod;}
int qpow(int a,int b){int c=1;while(b){if(b&1)c=mul(c,a);a=mul(a,a),b>>=1;}return c;}
struct Dot{
	int a[20][20],nn;
	void init(){
        for(int i=0;i<17;++i)
          for(int j=0;j<17;++j)a[i][j]=0;
	}
	int det(){
		int ans=1;
	    for(int i=1;i<=nn;++i){
	    	int id=-1;
	    	for(int j=i;j<=nn;++j)if(a[j][i]){id=j;break;}
	    	if(id==-1)return 0;
	    	if(id!=i)swap(a[i],a[id]),ans=(mod-ans)%mod;
	    	ans=mul(ans,a[i][i]);int inv=qpow(a[i][i],mod-2);
	    	for(int j=i;j<=nn;++j)a[i][j]=mul(a[i][j],inv);
	    	for(int j=i+1;j<=nn;++j)
	    		for(int k=nn;k>=i;--k)
				    sub(a[j][k],mul(a[j][i],a[i][k]));
		}
		return ans;
	}
}t;
int Nn,Popcnt[1<<16],n,Id[20];
int w[20][20];
void Add(int u,int v,int c){
	add(t.a[u][u],c),add(t.a[v][v],c);
	sub(t.a[u][v],c),sub(t.a[v][u],c);
}
int sum[20][1<<16],sum1[20][1<<16],cir[20];
int f[1<<16][20],F[1<<16],g[1<<16],G[1<<16];
void solve(){
	memset(cir,0,sizeof(cir)),cin>>n;
	for(int i=0;i<(1<<n);++i)
	    for(int j=1;j<=n;++j)f[i][j]=0;
	for(int i=1;i<(1<<n);++i)Popcnt[i]=Popcnt[i>>1]+(i&1); 
	for(int i=1;i<=n;++i)
	  for(int j=1;j<=n;++j)cin>>w[i][j];
	if(n==1){puts("1");return;}
	for(int i=1;i<=n;++i)
		for(int j=0;j<(1<<n);++j){
			sum[i][j]=0,sum1[i][j]=1;
			for(int k=0;k<n;++k)
			  if((j>>k)&1)add(sum[i][j],w[i][k+1]),sum1[i][j]=mul(sum1[i][j],w[i][k+1]+1);
			sub(sum1[i][j],1);
		}
	t.init(),t.nn=n-1;
	for(int i=1;i<=n;++i)
	  for(int j=i+1;j<=n;++j)Add(i,j,w[i][j]);
	int Ans_tree=t.det(),Ans=mul(n*(n-1)/2-n+1,Ans_tree);
    for(int i=1;i<=n;++i)f[(1<<i-1)][i]=1;
    for(int i=1;i<(1<<n);++i)
      for(int j=1;j<=n;++j)if(f[i][j])
        for(int k=1;k<=n;++k)if(!((i>>k-1)&1)&&(1<<k-1)>(i&-i))
          add(f[i|(1<<k-1)][k],mul(f[i][j],w[j][k]));
    for(int i=1;i<(1<<n);++i){
    	int ct=Popcnt[i],tt=0,ans1=0,id;
    	if(ct<3)continue;
    	for(int j=1;j<=n;++j)if((i>>j-1)&1){id=j;break;}
    	for(int j=1;j<=n;++j)if((i>>j-1)&1)add(ans1,mul(f[i][j],w[j][id]));
    	Nn=n-ct+1,t.init(),t.nn=Nn-1;
    	for(int j=1;j<=n;++j)if(!((i>>j-1)&1))Id[j]=++tt;else Id[j]=0;
    	for(int j=1;j<=n;++j)
    	  for(int k=j+1;k<=n;++k)
    	    if(Id[j]&&Id[k])Add(Id[j],Id[k],w[j][k]);
    	for(int j=1;j<=n;++j)if(Id[j])Add(Id[j],Nn,sum[j][i]);
    	ans1=mul(ans1,t.det()),ans1=mul(ans1,(mod+1>>1));
    	add(Ans,mul(ans1,ct*(ct-1)/2-ct+1));
	}
	for(int i=1;i<(1<<n);++i){
		Nn=Popcnt[i],t.init(),t.nn=Nn-1;int tt=0;
		for(int j=1;j<=n;++j)if((i>>j-1)&1)Id[j]=++tt;else Id[j]=0;
		for(int j=1;j<=n;++j)
    	  for(int k=j+1;k<=n;++k)
    	    if(Id[j]&&Id[k])Add(Id[j],Id[k],w[j][k]);
    	F[i]=t.det();
	}
	for(int i=1;i<=n;++i){
		g[0]=1;
		for(int j=1;j<(1<<n);++j){
			g[j]=0;if((j>>i-1)&1)continue;
			int s=(j^(j&-j)),t=(j&-j);
			for(int k=s;;k=((k-1)&s)){
				add(g[j],mul(F[k|t],mul(sum1[i][k|t],g[j^(k|t)])));
				if(!k)break;
			}
		}
		add(Ans,g[((1<<n)-1)^(1<<i-1)]);
	}
	for(int i=1;i<=n;++i)
	   for(int j=i+1;j<=n;++j){
	   	    g[0]=1;
	   	    for(int l=1;l<(1<<n);++l)G[l]=mul(F[l],(1ll*sum[i][l]*sum[j][l]+1ll*sum[i][l]+1ll*sum[j][l])%mod);
			for(int l=1;l<(1<<n);++l){
				g[l]=0;
				if((l>>i-1)&1)continue;
				if((l>>j-1)&1)continue;
				int s=(l^(l&-l)),t=(l&-l);
				i28 ans=0;
				for(int k=s;;k=((k-1)&s)){
					ans+=(i28)G[k|t]*(i28)g[l^(k|t)];
					if(!k)break;
				} 
				g[l]=ans%mod;
			}
			sub(Ans,mul(g[((1<<n)-1)^(1<<i-1)^(1<<j-1)],w[i][j]+1));
			for(int k=0;k<(1<<n);++k){
				if(((k>>i-1)&1)||((k>>j-1)&1))continue;
				int kk=k,s=(((1<<n)-1)^(1<<i-1)^(1<<j-1)^k);
				kk^=(1<<i-1),s^=(1<<j-1);
				add(Ans,mul(F[kk],F[s]));
			}
	   }
	cout<<Ans<<endl;
}
int main(){
	int T;cin>>T;
	while(T--)solve();
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1978ms
memory: 17948kb

input:

16
1
0
2
0 953763239
953763239 0
3
0 734999893 771971068
734999893 0 980773372
771971068 980773372 0
4
0 295218414 142837698 715328025
295218414 0 833169030 224028769
142837698 833169030 0 450275651
715328025 224028769 450275651 0
5
0 168127828 27116722 242318695 817220009
168127828 0 719973784 3288...

output:

1
953763239
858912196
425387299
913279760
958445240
55200517
150069607
303235124
105856735
869632234
877416619
919519535
312800965
893593717
127611854

result:

ok 16 lines