1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| #include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1000002;
int rt, n, m, R, Q, w, b[4][4], qres, cnt[maxn*2][16], id[64], tag[maxn*2], ri[maxn*2], ty[7], tot, iid[16], lc[maxn*2], rc[maxn*2], tol;
inline int getint() {
register int r = 0; register bool b = true; register char c = getchar();
while ('0' > c || c > '9') {if (c == '-') b = false; c = getchar();}
while ('0' <= c && c <= '9') {r = (r<<3)+(r<<1)+(c - '0'); c = getchar();}
if (b) return r;
return -r;
}
void build(int &now, int l, int r) {
now = ++tol;
if (l < r) {
int mid = (l + r) >> 1;
build(lc[now], l, mid);
build(rc[now], mid+1, r);
}
}
inline void Fill(int now, int t, int len) {
tag[now] = t;
for (int i = 0; i < tot; ++i) cnt[now][i] = 0;
if (len & 1) {
cnt[now][id[ty[t]]] = (len+1)/2;
cnt[now][id[0]] = len/2;
ri[now] = ty[t];
} else {
cnt[now][id[ty[t]]] = cnt[now][id[0]] = len/2;
ri[now] = 0;
}
}
inline void pushdown(int now, int l, int mid, int r) {
Fill(lc[now], tag[now], mid-l+1);
Fill(rc[now], tag[now], r-mid);
tag[now] = 0;
}
inline void pushup(int now) {
for (int i = 0; i < tot; ++i) cnt[now][i] = cnt[lc[now]][i] + cnt[rc[now]][id[iid[i]^ri[lc[now]]]];
ri[now] = ri[lc[now]] ^ ri[rc[now]];
}
void change(int now, int l, int r, int ll, int rr, int t) {
if (ll <= l && r <= rr) Fill(now, t, r-l+1);
else {
int mid = (l + r) >> 1;
if (tag[now] != 0) pushdown(now, l, mid, r);
if (ll <= mid) change(lc[now], l, mid, ll, rr, t);
if (rr > mid) change(rc[now], mid+1, r, ll, rr, t);
pushup(now);
}
}
void query(int now, int l, int r, int ll, int rr, int S) {
if (ll <= l && r <= rr) qres += cnt[now][id[S]];
else {
int mid = (l + r) >> 1;
if (tag[now] != 0) pushdown(now, l, mid, r);
if (ll <= mid) query(lc[now], l, mid, ll, rr, S);
if (rr > mid) query(rc[now], mid+1, r, ll, rr, S^ri[lc[now]]);
}
}
int main() {
n = getint(); m = getint();
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
w = w^(getint()<<(i*m+j));
int tmp;
for (int i = 0; i < n; ++i) {
tmp = 0;
for (int j = 0; j < n; ++j) for (int k = 0; k < m; ++k) b[j][k] = 0;
for (int j = 0; j < m; ++j) b[i][j] = 1;
for (int j = 0; j < n; ++j) for (int k = 0; k < m; ++k) tmp = tmp^(b[j][k]<<(j*m+k));
ty[i] = tmp;
}
for (int i = 0; i < m; ++i) {
tmp = 0;
for (int j = 0; j < n; ++j) for (int k = 0; k < m; ++k) b[j][k] = 0;
for (int j = 0; j < n; ++j) b[j][i] = 1;
for (int j = 0; j < n; ++j) for (int k = 0; k < m; ++k) tmp = tmp^(b[j][k]<<(j*m+k));
ty[i+n] = tmp;
}
int mx = 1<<(n+m), sta;
for (int i = 0; i < mx; ++i) {
sta = 0;
for (int j = 0; j < n+m; ++j) if (i&(1<<j)) sta ^= ty[j];
if (id[sta] == 0) id[sta] = ++tot;
}
R = getint(); Q = getint();
for (int i = n+m; i >= 1; --i) ty[i] = ty[i-1];
for (int i = 0; i < 64; ++i) {
--id[i];
if (id[i] != -1) iid[id[i]] = i;
}
build(rt, 1, R);
Fill(rt, 1, R);
int op, x, y;
while (Q--) {
op = getint(); x = getint(); y = getint();
if (op == 0) change(rt, 1, R, x, x, y);
else if (op == 1) { qres = 0; query(rt, 1, R, x, y, w); printf("%d\n", qres); }
else change(rt, 1, R, x, y, getint());
}
}
|