1. 程式人生 > >Wannafly挑戰賽18 C - 異或和

Wannafly挑戰賽18 C - 異或和

AC second ace #define stp AI -- print TP

思路:我剛開始是想旋轉四次坐標,每次用bit計算每個點左上角的點到這個點的距離,TLE了。。。。

這種算曼哈頓距離的可以將x 軸和 y 軸獨立開來,分別計算。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>

using namespace std;

const int N = 2000 + 7;
const int M = 1e6 + 7;
const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, m; LL x[N], y[N], sumx[N], fsumx[N], sumy[N], fsumy[N], num; char s[N][N]; inline void add(LL &a, LL b) { a += b; if(a >= mod) a -= mod; } LL fastPow(LL a, LL b) { LL ans = 1;
while(b) { if(b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans; } int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%s", s[i] + 1); } for(int i = 1; i <= n; i++) { for
(int j = 1; j <= m; j++) { if(s[i][j] == 1) { x[i]++; y[j]++; num++; } } } LL cnt = 0; for(int i = 1; i <= n; i++) add(sumx[i], sumx[i - 1]), add(sumx[i], cnt), add(cnt, x[i]); cnt = 0; for(int i = n; i >= 1; i--) add(fsumx[i], fsumx[i + 1]), add(fsumx[i], cnt), add(cnt, x[i]); cnt = 0; for(int i = 1; i <= m; i++) add(sumy[i], sumy[i - 1]), add(sumy[i], cnt), add(cnt, y[i]); cnt = 0; for(int i = m; i >= 1; i--) add(fsumy[i], fsumy[i + 1]), add(fsumy[i], cnt), add(cnt, y[i]); num = fastPow(num, mod - 2); LL ans = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { ans ^= (sumx[i] + fsumx[i] + sumy[j] + fsumy[j]) * num % mod; } } printf("%lld\n", ans); } /* */

Wannafly挑戰賽18 C - 異或和