第一個程式,計算所有的交點,並輸出,輸出格式是每行都是
a,b,c,d,e,f,g,h[i,j,s,t]
其中前面8個數表示這個交點是
a+bZ+cZ^2+dZ^3+eZ^4+fZ^5+gZ^6+hZ^7
後面四個數表示這個點是直線Z^i Z^j 和 直線Z^s Z^t的交點。
#include <stdio.h>
#include <process.h>
__int64 factor(__int64 a,__int64 b){
if(b==0)return a;
else return factor(b,a%b);
}
class Q{
__int64 _up;
__int64 _down;
void Normalize(){
__int64 fac=factor(_up,_down);
_down/=fac;
_up/=fac;
if(_down<0){
_down=-_down;
_up=-_up;
}
}
public:
Q():_up(0),_down(1){}
Q(__int64 up,__int64 down):_up(up),_down(down){}
Q(__int64 x):_up(x),_down(1){}
Q& operator+=(const Q& x);
Q& operator-=(const Q& x);
Q& operator*=(const Q& x);
Q& operator/=(const Q& x);
Q operator-()const{Q tmp=*this;tmp._up=-_up;return tmp;}
Q operator+(const Q& x)const{Q tmp=*this;tmp+=x;return tmp;}
Q operator-(const Q& x)const{Q tmp=*this;tmp-=x;return tmp;}
Q operator*(const Q& x)const{Q tmp=*this;tmp*=x;return tmp;}
Q operator/(const Q& x)const{Q tmp=*this;tmp/=x;return tmp;}
bool iszero()const{return _up==0;}
bool operator==(const Q& x)const{return _up==x._up&&_down==x._down;}
void output()const{if(_down==1)printf("% 4I64d",_up);else printf("% 2I64d/%I64d",_up,_down);}
};
Q& Q::operator +=(const Q& x){
_up=_up*x._down+_down*x._up;
_down*=x._down;
Normalize();
return *this;
}
Q& Q::operator -=(const Q& x){
_up=_up*x._down-_down*x._up;
_down*=x._down;
Normalize();
return *this;
}
Q& Q::operator *=(const Q& x){
_up*=x._up;
_down*=x._down;
Normalize();
return *this;
}
Q& Q::operator /=(const Q& x){
_up*=x._down;
_down*=x._up;
Normalize();
return *this;
}
Q mod[9]={Q(1),Q(1),Q(0),Q(-1),Q(-1),Q(-1),Q(0),Q(1),Q(1)};
void Mod(Q a[15]){
int i,j;
for(i=14;i>=8;i--){
Q divider=a[ i ];
for(j=0;j<=8;j++){
a[i-j]-=divider*mod[8-j];
}
}
}
void Dump(const Q M[15][15], const Q b[15]){
int i,j;
printf("//n//n");
for(i=0;i<15;i++){
for(j=0;j<14;j++){
M[j][ i ].output();
printf(",");
}
M[j][ i ].output();
printf("=");
b[ i ].output();
printf("//n");
}
}
void SolveEquation(Q M[8][8],Q b[15]){
int i,j,k;
for(i=0;i<8;i++){
// Dump(M,b);
for(j=i;j<8;j++)
if(!M[ i ][j].iszero())break;
if(j!=i){
if(j>=8){
printf("There/'s no inverse for the matrix//n");
exit(-1);
}
for(k=0;k<8;k++){
Q tmp=M[k][ i ];
M[k][ i ]=M[k][j];
M[k][j]=tmp;
}
Q tmp=b[ i ];
b[ i ]=b[j];
b[j]=tmp;
}
Q divider=M[ i ][ i ];
for(j=i;j<8;j++)M[j][ i ]/=divider;
b[ i ]/=divider;
for(j=0;j<8;j++){
if(j==i)continue;
Q mult=M[ i ][j];
for(k=i;k<8;k++)M[k][j]-=mult*M[k][ i ];
b[j]-=mult*b[ i ];
}
}
}
void Inverse(const Q a[15], Q b[15]){
Q M[8][8];
Q tmp[15];
int i,j;
for(i=0;i<8;i++){
for(j=0;j<15;j++)tmp[j]=Q(0);
for(j=0;j<8;j++)tmp[i+j]=a[j];
Mod(tmp);
for(j=0;j<8;j++){
M[ i ][j]=tmp[j];
}
}
b[0]=Q(1);
for(i=1;i<15;i++)b[ i ]=Q(0);
SolveEquation(M,b);
}
void Multiple(const Q a[15], const Q b[15], Q c[15]){
int i,j;
for(i=0;i<15;i++)c=Q(0);
for(i=0;i<15;i++)for(j=0;j<15;j++){
if(i+j<15){
c[i+j]+=a[ i ]*b[ j ];
}else{
c[i+j-15]-=a[ i ]*b[ j ];
}
}
Mod(c);
}
void Output(const Q r[15],int i,int j,int s,int k){
int u;
for(u=0;u<7;u++){
r[u].output();
printf(",");
}
r[u].output();
printf("[%d,%d,%d,%d]//n",i,j,s,k);
}
#define INC(z, x) do{//
int tmp=(x)%30;if(tmp<0)tmp+=30;//
if(tmp<15)(z)[tmp]+=Q(1);//
else (z)[tmp-15]-=Q(1);//
}while(0)
#define DEC(z, x) do{//
int tmp=(x)%30;if(tmp<0)tmp+=30;//
if(tmp<15)(z)[tmp]-=Q(1);//
else (z)[tmp-15]+=Q(1);//
}while(0)
void Find(int i,int j,int s,int t){
int k;
// printf("%d %d %d %d//n",i,j,s,t);
Q delta[15],invdelta[15],r[15];
for(k=0;k<15;k++){
delta[k]=0;
}
INC(delta,j-t);DEC(delta,i-t);DEC(delta,j-s);INC(delta,i-s);
DEC(delta,t-j);INC(delta,t-i);INC(delta,s-j);DEC(delta,s-i);
Mod(delta);
Inverse(delta,invdelta);
for(k=0;k<15;k++)delta[k]=0;
INC(delta,i-j+s);DEC(delta,i-j+t);DEC(delta,-i+j+s);INC(delta,-i+j+t);
INC(delta,j+s-t);DEC(delta,i+s-t);DEC(delta,j-s+t);INC(delta,i-s+t);
Mod(delta);
Multiple(invdelta,delta,r);
Output(r,i,j,s,t);
}
int main(){
int i,j,s,t;
for(i=0;i<30;i++)for(s=i+1;s<30;s++)for(j=s+1;j<30;j++)for(t=j+1;t<30;t++){
Find(i,j,s,t);
}
}