3288: Mato矩阵
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 348 Solved: 269
[ Submit][ Status][ Discuss]
Description
Mato同学最近正在研究一种矩阵,这种矩阵有n行n列第i行第j列的数为gcd(i,j)。
例如n=5时,矩阵如下:
1 1 1 1 1
1 2 1 2 1
1 1 3 1 1
1 2 1 4 1
1 1 1 1 5
Mato想知道这个矩阵的行列式的值,你能求出来吗?
例如n=5时,矩阵如下:
1 1 1 1 1
1 2 1 2 1
1 1 3 1 1
1 2 1 4 1
1 1 1 1 5
Mato想知道这个矩阵的行列式的值,你能求出来吗?
Input
一个正整数n mod1000000007
Output
n行n列的Mato矩阵的行列式。
Sample Input
5
Sample Output
16
HINT
对于100%的数据,n<=1000000。
通过打表得到,这个矩阵通过化简,主对角线的值为欧拉函数值
打表代码如下:
#include<math.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
const double eps=1e-9;
int equ,var;
double arr[20][20];
int Gauss()
{
int row=0,col=0;
for(;row<equ&&col<var;row++,col++){
int max_r=row;
for(int i=row+1;i<equ;i++)
if(fabs(arr[i][col])>fabs(arr[max_r][col])) max_r=i;
if(fabs(arr[max_r][col])<eps) return 0;
if(row!=max_r)
for(int j=col;j<var;j++)
swap(arr[row][j],arr[max_r][j]);
for(int i=row+1;i<equ;i++)
for(int j=col+1;j<var;j++)
arr[i][j]-=arr[i][col]*arr[row][j]/arr[row][col];
}
return 1;
}
int main()
{
int n=15;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
arr[i][j]=gcd(i+1,j+1);
equ=var=n;
Gauss();
for(int i=0;i<n;i++)
printf("%d ",(int)arr[i][i]);
return 0;
}
然后就是线性筛法一弄就好了
#include<stdio.h>
#include<algorithm>
#define MOD 1000000007
using namespace std;
int n;
long long ans=1;
#define MAXN 1000010
int phi[MAXN],prime[MAXN],tot;
bool not_prime[MAXN];
void Linear_euler()
{
phi[1]=1;
for(int i=2;i<=MAXN;i++){
if(!not_prime[i]) prime[++tot]=i,phi[i]=i-1;
for(int j=1;prime[j]*i<=MAXN;j++){
not_prime[prime[j]*i]=1;
if(i%prime[j]==0){ phi[prime[j]*i]=phi[i]*prime[j]; break;}
phi[prime[j]*i]=phi[i]*(prime[j]-1);
}
}
}
int main()
{
Linear_euler();
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
ans*=phi[i],ans%=MOD;
printf("%lld\n",ans);
}
return 0;
}