QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#454679#8821. NightmarePhantomThresholdRE 919ms18996kbC++175.8kb2024-06-25 09:31:022024-06-25 09:31:02

Judging History

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

  • [2024-06-25 09:31:02]
  • 评测
  • 测评结果:RE
  • 用时:919ms
  • 内存:18996kb
  • [2024-06-25 09:31:02]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

ll n,mod;

inline ll ksm(ll a,ll x){
	ll ret=1;
	for (;x;x>>=1,a=a*a%mod) if (x&1) ret=ret*a%mod;
	return ret;	
}
inline ll inv(ll a){return ksm(a,mod-2);}

inline void add(ll &A,ll B){A+=B;if (A>=mod) A-=mod;}
inline void sub(ll &A,ll B){A-=B;if (A<0) A+=mod;}

struct matrix{
	ll m[505][505];
	matrix(){
		memset(m,0,sizeof(m));
	}
	void diag(){
		for (int i=1;i<=n+1;i++){
			for (int j=1;j<=n+1;j++){
				m[i][j]=(i==j);	
			}
		}
	}
	friend matrix operator * (const matrix &A,const matrix &B){
		matrix C;
		for (int i=1;i<=n+1;i++){
			for (int k=1;k<=n+1;k++){
				for (int j=1;j<=n+1;j++) (C.m[i][j]+=A.m[i][k]*B.m[k][j])%=mod;
			}
		}
		return C;
	}
	void add_row(int x,int y,ll k){
		for (int i=1;i<=n+1;i++) (m[y][i]+=m[x][i]*k)%=mod;
	}
	void add_col(int x,int y,ll k){
		for (int i=1;i<=n+1;i++) (m[i][y]+=m[i][x]*k)%=mod;
	}
	void swap_row(int x,int y){
		for (int i=1;i<=n+1;i++) swap(m[y][i],m[x][i]);
	}
	void swap_col(int x,int y){
		for (int i=1;i<=n+1;i++) swap(m[i][y],m[i][x]);
	}
	void mul_row(int x,ll k){
		for (int i=1;i<=n+1;i++) m[x][i]=m[x][i]*k%mod;
	}
	void mul_col(int x,ll k){
		for (int i=1;i<=n+1;i++) m[i][x]=m[i][x]*k%mod;
	}
	matrix turn(){
		matrix ans;
		for (int i=1;i<=n+1;i++){
			for (int j=1;j<=n+1;j++){
				ans.m[i][j]=m[j][i];
			}
		}
		return ans;
	}
	void display(){
		for (int i=1;i<=n+1;i++){
			for (int j=1;j<=n+1;j++){
				cerr << m[i][j] << " ";	
			}
			cerr << endl;
		}
	}
};

matrix G,oriG;
matrix P,Pbase;
matrix PTP;

const int maxn=1000000;
ll sq[maxn+50];
ll g=1,ig=1;
ll gx,gy;

void getg(){
	for (;g<mod;g++){
		bool flag=1;
		for (int i=1;i<mod-1;i++) if (ksm(g,i)==1){flag=0;break;}
		if (flag){
			ig=inv(g);
			for (ll i=0;i<n;i++){
				ll j2=(g-i*i%mod+mod)%mod;
				if (sq[j2]!=-1){
					gx=i;
					gy=sq[j2];
					break;
				}
			}
			return;
		}
	}
}

int main(){
	cin >> n >> mod;
	for (int i=0;i<mod;i++) sq[i]=-1;
	for (int i=0;i<=mod/2;i++) sq[i*i%mod]=i;
	
	getg();
	
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cin >> oriG.m[i][j];
			G.m[i][j]=oriG.m[i][j];
		}
	}
	P.diag();
	int rk=0;
	for (int i=1;i<=n;i++){
		if (G.m[i][i]==0){
			int pos=0;
			for (int j=i+1;j<=n;j++){
				if (G.m[j][j]!=0){
					pos=j;
					break;
				}
			}
			if (pos!=0){
				P.swap_col(i,pos);
				G.swap_row(i,pos);
				G.swap_col(i,pos);
			}	
		}
		
		if (G.m[i][i]!=0){
			ll iv=inv(G.m[i][i]);
			for (int j=i+1;j<=n;j++){
				ll coef=iv*G.m[j][i]%mod;
				P.add_col(j,i,coef);
				G.add_row(i,j,mod-coef);
				G.add_col(i,j,mod-coef);	
			}
			ll sqiv=sq[iv];
			if (sqiv==-1) sqiv=sq[iv*g%mod];
			P.mul_col(i,sqiv);
			G.mul_row(i,sqiv);
			G.mul_col(i,sqiv);
		}
		else if (i<n){
			{
				int pos=0;
				for (int j=i+1;j<=n;j++) if (G.m[j][i]!=0) pos=i;
				if (pos!=0){
					P.swap_col(i+1,pos);
					G.swap_row(i+1,pos);
					G.swap_col(i+1,pos);
				}
			}
			if (G.m[i+1][i]==0) continue;
			ll iv=G.m[i+1][i];
			for (int j=i+2;j<=n;j++){
				ll coef=iv*G.m[j][i]%mod;
				P.add_col(j,i+1,coef);
				G.add_row(i+1,j,mod-coef);
				G.add_col(i+1,j,mod-coef);	
			}
			if (mod!=2){
				ll i2=inv(2);
				P.add_col(i,i+1,mod-1);
				G.add_row(i+1,i,1);
				G.add_col(i+1,i,1);
				
				P.add_col(i+1,i,i2);
				G.add_row(i,i+1,mod-i2);
				G.add_col(i,i+1,mod-i2);
				
				ll sqiv=sq[inv(G.m[i][i])];
				if (sqiv==-1) sqiv=sq[inv(G.m[i][i])*g%mod];
				P.mul_col(i,sqiv);
				G.mul_row(i,sqiv);
				G.mul_col(i,sqiv);
				
				P.mul_col(i+1,sqiv);
				G.mul_row(i+1,sqiv);
				G.mul_col(i+1,sqiv);
			}
		}
	}
//	cerr << "-----------------" << endl;
//	cerr << "G : " << endl;
//	G.display();
//	cerr << "P : " << endl;
//	P.display();
//	cerr << "PGPT : " << endl;
//	matrix tmp=P*G*P.turn();
//	tmp.display();
	
	if (mod!=2){
		int rk1=0;
		for (int i=1;i<=n;i++) if (G.m[i][i]==g){
			rk1++;
			P.swap_col(i,rk1);
			G.swap_row(i,rk1);
			G.swap_col(i,rk1);	
		}
		rk=rk1;
		for (int i=rk1+1;i<=n;i++) if (G.m[i][i]==1){
			rk++;
			P.swap_col(i,rk);
			G.swap_row(i,rk);
			G.swap_col(i,rk);	
		}
		assert(rk1%2==0);
		for (int i=1;i<=rk1;i+=2){
			for (int j=1;j<=n;j++){
				ll tmpA=(G.m[j][i]*gx+G.m[j][i+1]*(mod-gy))%mod;
				ll tmpB=(G.m[j][i]*gy+G.m[j][i+1]*gx)%mod;
				G.m[j][i]=tmpA;
				G.m[j][i+1]=tmpB;
			}
		}
	}
	else{
		int rk1=0;
		for (int i=1;i<n;i++) if (G.m[i][i]==0 && G.m[i+1][i]==1){
			rk1+=2;
			P.swap_col(i,rk1-1);
			G.swap_row(i,rk1-1);
			G.swap_col(i,rk1-1);
			P.swap_col(i+1,rk1);
			G.swap_row(i+1,rk1);
			G.swap_col(i+1,rk1);	
		}
		rk=rk1;
		for (int i=rk1+1;i<=n;i++) if (G.m[i][i]==1){
			rk++;
			P.swap_col(i,rk);
			G.swap_row(i,rk);
			G.swap_col(i,rk);	
		}
//		assert(!(rk1==rk && rk==n));
		
//		cerr << "-----------------" << endl;
//		cerr << "G : " << endl;
//		G.display();
//		cerr << "P : " << endl;
//		P.display();
//		cerr << "PGPT : " << endl;
//		matrix tmp=P*G*P.turn();
//		tmp.display();
		
		rk=max(rk,rk1+1);
		for (int i=1;i<=rk1;i+=2){
			for (int j=1;j<=n;j++){
				ll A=P.m[j][i];
				ll B=P.m[j][i+1];
				ll C=P.m[j][rk];
				
				P.m[j][i]=(A+C)%mod;
				P.m[j][i+1]=(A+B+C)%mod;
				P.m[j][rk]=(B+C)%mod;
			}
			G.swap_row(i+1,i);
		}
		if (G.m[rk][rk]==0){
			for (int i=1;i<=n+1;i++) P.m[rk][i]=0;
		}
	}
	
	for (int i=1;i<=n;i++){
		for (int j=rk+1;j<=n+1;j++){
			P.m[i][j]=0;
		}
	}
	for (int i=1;i<=n+1;i++) P.m[n+1][i]=0;
	
	cout << rk << "\n";
	for (int i=1;i<=n;i++){
		for (int j=1;j<=rk;j++){
			cout << P.m[i][j] << " \n"[j==rk];
		}
	}
	
//	cerr << "------check---------" << endl;
	PTP=P*P.turn();
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++) assert(PTP.m[i][j]==oriG.m[i][j]);	
	}
//	PTP.display();
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 18996kb

input:

2 2
1 1
1 1

output:

1
1
1

result:

ok accepted

Test #2:

score: 0
Accepted
time: 0ms
memory: 17620kb

input:

3 5
4 4 3
4 4 3
3 3 2

output:

2
2 0
2 0
4 1

result:

ok accepted

Test #3:

score: 0
Accepted
time: 919ms
memory: 17928kb

input:

500 2
1 0 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 0 1 0 0 ...

output:

423
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

result:

ok accepted

Test #4:

score: -100
Runtime Error

input:

500 2
0 0 1 0 0 1 1 0 1 0 1 0 0 0 0 1 0 0 1 0 1 1 0 1 1 0 1 0 1 0 1 0 0 0 1 0 1 1 1 1 1 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1 0 1 0 1 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 1 1 0 0 1 ...

output:

494
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

result: