• XTU 1260


    是2017江苏省赛的第一题,当时在场上没做出来(废话,那个时候又不懂高斯消元怎么写……而且数论也学得一塌糊涂,现在回来补了)

    省赛结束之后,题解pdf就出来了,一看题解,嗯……加一行再求逆矩阵从而得到伴随矩阵从而得到答案,emmmmm真是非常通俗易懂呢!

    于是在回学校的路上强行回忆上学期学的线性代数,把这题题解的原理想通了,然后到现在把高斯消元法补了,才把这题做出来……

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define MAXN 205
     4 #define MOD 1000000007
     5 typedef long long ll;
     6 using namespace std;
     7 int n;
     8 ll a[MAXN][2*MAXN],det;//注意矩阵的列数要是MAXN的两倍,因为( A , E ) -> ( E , inv(A) ) 
     9 ll pow(ll a,ll b){//快速幂 
    10     ll r=1,base=a%MOD;
    11     while(b){
    12         if(b&1) r*=base , r%=MOD;
    13         base*=base;
    14         base%=MOD;
    15         b>>=1;
    16     }
    17     return r;
    18 }
    19 ll inv_(ll a){return pow(a,MOD-2);}//求逆元 
    20 void debug()
    21 {
    22     for(int i=1;i<=n;i++)
    23     {
    24         for(int j=1;j<=2*n;j++) printf("%I64d ",a[i][j]);
    25         printf("
    ");
    26     }
    27 }
    28 int Gauss_eli(int row,int col)
    29 {
    30     det=1;
    31     for(int i=1;i<=row;i++)//a[i][i] 
    32     {
    33         int tmp;
    34         for(tmp=i;tmp<=n;tmp++) if(a[tmp][i]) break;
    35         if(tmp!=i) det*=-1;//行列式交换两行要取负
    36         for(int j=1;j<=col;j++) swap(a[tmp][j],a[i][j]);//交换两行
    37         det=(det*a[i][i]%MOD + MOD)%MOD;
    38         ll inv=inv_(a[i][i]);//求得逆元 
    39         for(int j=1;j<=col;j++) a[i][j]=a[i][j]*inv%MOD; 
    40         for(int r=1;r<=row;r++)
    41         {
    42             if(r==i) continue;
    43             ll mult=a[r][i];
    44             for(int c=1;c<=col;c++) a[r][c]=(a[r][c] - a[i][c]*mult%MOD + MOD)%MOD;//消元 
    45         }
    46         //debug(); printf("det = %I64d
    ",det);
    47     }
    48 }
    49 int main()
    50 {
    51     //freopen("input.txt","r",stdin);
    52     //freopen("output1.txt","w",stdout);
    53     while(scanf("%d",&n)!=EOF)
    54     {
    55         for(int j=1;j<=n;j++) a[1][j]=1;
    56         for(int i=2;i<=n;i++) for(int j=1;j<=n;j++) scanf("%lld",&a[i][j]);
    57         for(int i=1;i<=n;i++) for(int j=n+1;j<=2*n;j++) a[i][j]=(i==(j-n));
    58         Gauss_eli(n,2*n);
    59         for(int i=1;i<=n;i++)
    60         {
    61             if(i!=1) printf(" ");
    62             if(i%2==0) a[i][n+1]=(MOD - a[i][n+1])%MOD;
    63             printf("%I64d",(a[i][n+1]*det + MOD)%MOD);
    64         }
    65         printf("
    ");
    66     }
    67 }

    可以说是学到了,对高斯消元、逆元、取模等一系列问题有了更深的认识吧。

    关于快速幂:

    a^b,把b个a进行两两分组,比如:a*a*a*a*a*a  =>  (a*a)*(a*a)*(a*a)

    这样变的好处是,你只需要计算一次a*a,然后将结果(a*a)连乘自己两次就能得到a^6,即(a*a)^3=a^6。算一下发现这次一共乘了3次,少于原来的5次。

    核心代码是:

    1 while(n)
    2 {
    3     if(n&1) res=res*a;
    4     n>>=1;
    5     a=a*a;
    6 }

    完整版是:

     1 ll fpow(ll a,ll b){//快速幂
     2     ll r=1,base=a%MOD;
     3     while(b){
     4         if(b&1) r*=base , r%=MOD;
     5         base*=base;
     6         base%=MOD;
     7         b>>=1;
     8     }
     9     return r;
    10 }
    11 ll fpow(ll a,ll i){//递归版快速幂
    12   if (i==0) return 1;
    13   int temp=pow(a,i>>1);
    14   temp=temp*temp%MOD;
    15   if (i&1) temp=(ll)temp*a%MOD;
    16   return temp%MOD;
    17 }

    另附一个数据生成器,以后应该经常用得到……

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<ctime>
     4 int get_rand(int m,int n)//[m,n] 
     5 {
     6     return( rand()%(n - m + 1) + m );
     7 }
     8 int main()
     9 {
    10     freopen("input.txt","w",stdout);
    11     srand(time(NULL)); 
    12     int n=get_rand(1,200);
    13     printf("%d
    ",n);
    14     for(int i=1;i<n;i++)
    15     {
    16         for(int j=1;j<=n;j++) printf("%d ",get_rand(0,1000000009));
    17         printf("
    ");
    18     }
    19 }
    View Code
  • 相关阅读:
    lib-qqwry v1.0 发布 nodejs解析纯真IP库(qqwry.dat)
    queue-fun —— nodejs下基于Promise的队列控制模块。
    javascript 高效按字节截取字符串
    最短JS判断是否为IE6(IE的写法) (转)
    javascript把IP地址转为数值几种方案,来挑战一下效率吧
    Android的ViewPager的学习
    【感悟】一次不太好的寻找bug的体验,RecyclerView
    Android的SQlite的使用
    Android的几种Manager
    Android的Service的创建与使用
  • 原文地址:https://www.cnblogs.com/dilthey/p/7127575.html
Copyright © 2020-2023  润新知