A1488. 魔法波(乔明达)
设si表示表示每个格子的状态(1表示腐地,0表示土地),xi表示对每个格子的操作状态(1表示发射,0表示不发射),可以列出异或方程si^sigma(xj)=1
然而介四O(n^6),BOOM
于是我们把格子分成横向(Yl)和纵向(Yr)的块,每一个块代表能对其中的格子产生影响的格子的集合,所以我们有,,,这里请把sigma理解为异或和
Y=sigma(xi) ①
si^sigma(Ylj)^sigma(Yrj)^xi=1 ②
把②移项得xi=si^sigma(Ylj)^sigma(Yrj)^1 ③
把③带入①得sigma(Ylj)^sigma(Yrj)=Yi^sigma(sj)^sigma(1) ④
然而只能A50%,内心崩溃
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 805 4 bitset<2005>B[2005]; 5 char Map[maxn][maxn]; 6 int num,Yl[maxn][maxn],Yr[maxn][maxn],ans[2005]; 7 void gauss() { 8 int i, j, k; 9 for(i=0,k=0; i<num; i++) { 10 for(j=k; j<num; j++) { 11 if(B[j][i]==1) { 12 if(j!=k) swap(B[j],B[k]); 13 break; 14 } 15 } 16 if(j==num) continue; 17 for(j=k+1; j<num; j++) { 18 if(B[j][i]==1) { 19 B[j] ^= B[k]; 20 } 21 } 22 k ++; 23 } 24 for(i=0; i<num; i++) ans[i] = -1; 25 for(i=num-1; i>=0; i--) { 26 int res = B[i][num]; 27 for(j=num-1; j>=i; j--) { 28 if(B[i][j]) { 29 if(ans[j]<0) ans[j] = res; 30 res ^= ans[j]; 31 } 32 } 33 } 34 } 35 int main(){ 36 int n; 37 scanf("%d",&n); 38 for(int i=1;i<=n;i++) 39 scanf("%s",Map[i]+1); 40 for(int j=1;j<=n;j++){ 41 Map[0][j]='X'; 42 for(int i=1;i<=n;i++){ 43 if(Map[i][j]=='X')continue; 44 if(Map[i-1][j]=='X')Yr[i][j]=num++; 45 else Yr[i][j]=Yr[i-1][j]; 46 } 47 } 48 for(int i=1;i<=n;i++){ 49 Map[i][0]='X'; 50 for(int j=1;j<=n;j++){ 51 if(Map[i][j]=='X')continue; 52 if(Map[i][j-1]=='X')Yl[i][j]=num++; 53 else Yl[i][j]=Yl[i][j-1]; 54 } 55 } 56 57 for(int i=0;i<num;i++)B[i].set(i); 58 for(int i=1;i<=n;i++) 59 for(int j=1;j<=n;j++){ 60 if(Map[i][j]=='X')continue; 61 int l=Yl[i][j],r=Yr[i][j],x=Map[i][j]-'0'; 62 B[l].flip(l),B[l].flip(r); 63 B[r].flip(l),B[r].flip(r); 64 if(x^1)B[l].flip(num),B[r].flip(num); 65 } 66 for(int i=0;i<num;i++){ 67 for(int j=0;j<=num;j++) 68 printf("%d",B[i][j]?1:0); 69 printf("\n"); 70 } 71 printf("\n"); 72 gauss(); 73 for(int i=0;i<num;i++){ 74 for(int j=0;j<=num;j++) 75 printf("%d",B[i][j]?1:0); 76 printf("\n"); 77 } 78 for(int i=1;i<=n;i++){ 79 for(int j=1;j<=n;j++){ 80 if(Map[i][j]=='X')printf("0"); 81 else printf("%d",(Map[i][j]-'0')^ans[Yl[i][j]]^ans[Yr[i][j]]^1); 82 } 83 printf("\n"); 84 } 85 return 0; 86 }