日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

线性代数一之矩阵转向量随机化求解——神奇的矩阵(BZOJ)+向量内积

發布時間:2023/12/3 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线性代数一之矩阵转向量随机化求解——神奇的矩阵(BZOJ)+向量内积 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

向量隨機化

  • 神奇的矩陣
    • description
    • solution
    • code
  • [NOI2013]向量內積
    • description
    • solution
    • code

矩陣既可以看成是一張數位表,也可以看成是若干個行向量或者若干個列向量的向量表

神奇的矩陣

description

solution

暴力做A?BA*BA?B會達到n3n^3n3的復雜度,難以接受

考慮,如果對于矩陣A,B,CA,B,CA,B,C滿足A?B=CA*B=CA?B=C,顯然有A?B?R=C?RA*B*R=C*RA?B?R=C?R

于是有隨機一個1×n1\times n1×n的向量RRR,然后check等式是否成立,A?R?BA*R*BA?R?B就會降成n2n^2n2的復雜度

隨機多次都無法滿足這個式子,A?B=CA*B=CA?B=C的概率就微乎其微(除非你是非酋)

code

#include <bits/stdc++.h> using namespace std; #define int long long int n;struct matrix {int n, m;int c[1000][1000];matrix() {memset( c, 0, sizeof( c ) );}matrix operator * ( matrix &t ) {matrix ans;ans.n = n, ans.m = t.m;for( int i = 0;i <= n;i ++ )for( int j = 0;j <= t.m;j ++ )for( int k = 0;k <= m;k ++ )ans.c[i][j] += c[i][k] * t.c[k][j];return ans;} }A, B, C, R, ans1, ans2;signed main() {srand( time( 0 ) );next :while( ~ scanf( "%lld", &n ) ) {n --;A.n = A.m = B.n = B.m = C.n = C.m = n;for( int i = 0;i <= n;i ++ )for( int j = 0;j <= n;j ++ )scanf( "%lld", &A.c[i][j] );for( int i = 0;i <= n;i ++ )for( int j = 0;j <= n;j ++ )scanf( "%lld", &B.c[i][j] );for( int i = 0;i <= n;i ++ )for( int j = 0;j <= n;j ++ )scanf( "%lld", &C.c[i][j] );int t = 30;again :while( t -- ) {R.n = 0, R.m = n;for( int i = 0;i <= n;i ++ )R.c[0][i] = rand();ans1 = R * A * B;ans2 = R * C;for( int i = 0;i <= n;i ++ )if( ans1.c[0][i] != ans2.c[0][i] )goto again;printf( "Yes\n" );goto next;}printf( "No\n" );}return 0; }

[NOI2013]向量內積

description

solution

  • k=2

    • 求出矩陣兩兩內積(mod2)\pmod 2(mod2) ,即Y=A?ATY=A*A^TY=A?AT
    • 接下來就是判斷Y=E,EY=E,EY=E,E為全111矩陣(Yi,jY_{i,j}Yi,j?代表著AAAiii行向量與ATA^TATjjj列向量也就是原來的AjA_jAj?行向量的內積)因為如果全111代表著每兩個向量的內積都為1(mod2)1\pmod 21(mod2)
      • 判斷方法就是上一題的隨機化
      • 只要不等,就會有一個000向量,找到其位置pospospos,最后暴力求每個向量與其的內積是否整除kkk即可
  • k=3,此時Ai,j=0/1/2A_{i,j}=0/1/2Ai,j?=0/1/2,不能在使用上述EEE來判斷了

    • 轉換一下即可,Zi,j=Yi,j2(mod3)Z_{i,j}=Y_{i,j}^2\pmod 3Zi,j?=Yi,j2?(mod3),有12≡23≡1(mod3)1^2\equiv 2^3\equiv 1\pmod 312231(mod3),只有02≡0(mod3)0^2\equiv 0\pmod3020(mod3)

    • 再次使用EEE來進行判斷

    • 問題在于,ZZZYYY每個單項的平方,不是整體的平方,不能使用矩陣快速得到

      • α\alphaα是隨機的一個1×n1\times n1×n向量

      • (Z?α)i=∑j=1nZi,j?αj=∑j=1nYi,j2?αj=∑j=1nαj(∑k=1nAi,kAk,jT)2(Z*\alpha)_i=\sum_{j=1}^nZ_{i,j}*\alpha_j=\sum_{j=1}^nY_{i,j}^2*\alpha_j=\sum_{j=1}^n\alpha_j\bigg(\sum_{k=1}^nA_{i,k}A^T_{k,j}\bigg)^2(Z?α)i?=j=1n?Zi,j??αj?=j=1n?Yi,j2??αj?=j=1n?αj?(k=1n?Ai,k?Ak,jT?)2

        =∑j=1nαj∑k1=1nAi,k1Ak1,jT?∑j=1nαj∑k2=1nAi,k2Ak2,jT=\sum_{j=1}^n\alpha_j\sum_{k_1=1}^nA_{i,k_1}A^T_{k_1,j}*\sum_{j=1}^n\alpha_j\sum_{k_2=1}^nA_{i,k_2}A^T_{k_2,j}=j=1n?αj?k1?=1n?Ai,k1??Ak1?,jT??j=1n?αj?k2?=1n?Ai,k2??Ak2?,jT?

      • 發現可以變為∑k1,k2Ai,k1Ai,k2?∑j=1nαjAk1,jAk2,jT\sum_{k_1,k_2}A_{i,k_1}A_{i,k_2}*\sum_{j=1}^n\alpha_jA_{k_1,j}A^T_{k_2,j}k1?,k2??Ai,k1??Ai,k2???j=1n?αj?Ak1?,j?Ak2?,jT?

        預處理出和iii無關部分,設gk1,k2=∑j=1nαjAk1,jAk2,jTg_{k_1,k_2}=\sum_{j=1}^n\alpha_jA_{k_1,j}A^T_{k_2,j}gk1?,k2??=j=1n?αj?Ak1?,j?Ak2?,jT?

code

#include <bits/stdc++.h> using namespace std; #define int long long #define maxn 100005 #define maxd 105 int n, d, k, sum, pos, flag; int x[maxn][maxd], g[maxn][maxd]; int ret[maxd], r[maxn];void calc2() {for( int i = 1;i <= d;i ++ ) ret[i] = 0;for( int i = 1;i <= d;i ++ )for( int j = 1;j <= n;j ++ )ret[i] = ( ret[i] + r[j] * x[j][i] ) % k;for( int i = 1;i <= n;i ++ ) {int ans = 0;for( int j = 1;j <= d;j ++ )ans = ( ans + ret[j] * x[i][j] ) % k;if( ans != sum ) {pos = i, flag = 1;break;}} }void calc3() {for( int k1 = 1;k1 <= d;k1 ++ )for( int k2 = 1;k2 <= d;k2 ++ ) {g[k1][k2] = 0;for( int j = 1;j <= n;j ++ )g[k1][k2] = ( g[k1][k2] + r[j] * x[j][k1] % k * x[j][k2] ) % k;}for( int i = 1;i <= n;i ++ ) {int ans = 0;for( int k1 = 1;k1 <= d;k1 ++ )for( int k2 = 1;k2 <= d;k2 ++ )ans = ( ans + x[i][k1] * x[i][k2] % k * g[k1][k2] ) % k;if( ans != sum ) {pos = i, flag = 1;break;}} }signed main() {srand( time( 0 ) );scanf( "%lld %lld %lld", &n, &d, &k );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= d;j ++ )scanf( "%lld", &x[i][j] ); for( int T = 1;T <= 6;T ++ ) {sum = 0;for( int i = 1;i <= n;i ++ )r[i] = rand() % k, sum = ( sum + r[i] ) % k;if( k == 2 ) calc2();else calc3();if( flag ) break;}if( ! flag ) return ! printf( "-1 -1\n" );else {for( int i = 1;i <= n;i ++ )if( i ^ pos ) {int ans = 0;for( int j = 1;j <= d;j ++ )ans = ( ans + x[i][j] * x[pos][j] ) % k;if( ! ans ) return ! printf( "%lld %lld\n", min( i, pos ), max( i, pos ) );}}return 0; }

總結

以上是生活随笔為你收集整理的线性代数一之矩阵转向量随机化求解——神奇的矩阵(BZOJ)+向量内积的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。