题目链接
题解
按位处理。
把每一位对应的图都处理出来
然后单调栈处理一下就好了。
\(and\)操作处理全\(1\)。
\(or\)操作处理全\(0\)。
代码
#include <bits/stdc++.h>
#define gc getchar
using namespace std;
typedef long long ll;
const int N = 1000 + 4;
const int P = 1e9 + 7;
const int BIT = 31;
int n;
ll ans = 0ll;
ll sum[N][N];
int stk[N];
template <typename T> void read(T &x) {
x = 0; T fl = 1; char c = 0;
for (; c < '0' || c > '9'; c = gc()) if (c == '-') fl = -1;
for (; c >= '0' && c <= '9'; c = gc()) x = (x << 1) + (x << 3) + (c ^ 48);
x *= fl;
}
struct Matrix_BIT {
int a[N][N];
} mat[BIT + 5];
int main() {
cin >> n;
for (int i = 1; i <= n; i ++)
for (int j = 1, x; j <= n; j ++) {
read(x);
for (int k = 0; k <= BIT; k ++) mat[k].a[i][j] = (x >> k) & 1;
}
ans = 0ll;
for (int k = 0; k <= BIT; k ++) {
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
if (mat[k].a[i][j] == 1) sum[i][j] = sum[i - 1][j] + 1;
else sum[i][j] = 0;
for (int i = 1; i <= n; i ++) {
ll res = 0ll; int top = 0;
for (int j = 1; j <= n; j ++) {
res += sum[i][j];
while (top && sum[i][stk[top]] >= sum[i][j]) {
res -= (stk[top] - stk[top - 1]) * (sum[i][stk[top]] - sum[i][j]);
-- top;
}
ans = (ans + (res << k)) % P;
stk[++ top] = j;
}
}
}
printf("%lld ", ans); ans = 0ll;
for (int k = 0; k <= BIT; k ++) {
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
if (mat[k].a[i][j] == 0) sum[i][j] = sum[i - 1][j] + 1;
else sum[i][j] = 0;
for (int i = 1; i <= n; i ++) {
ll res = 0; int top = 0;
for (int j = 1; j <= n; j ++) {
res += sum[i][j];
while (top && sum[i][stk[top]] >= sum[i][j]) {
res -= (stk[top] - stk[top - 1]) * (sum[i][stk[top]] - sum[i][j]);
-- top;
}
ans = (ans + ((1ll * i * j - res) << k)) % P;
stk[++ top] = j;
}
}
}
printf("%lld\n", ans);
return 0;
}