const int MAXN = 100005;
const int MO = 10000007;
int a[MAXN], b[MAXN];
int n, m;
ll ans;
struct Hash {
int h[MO];
int v[MAXN], nxt[MAXN], cnt;
int geth(int x) {
return x % MO;
}
void insert(int x) {
v[++cnt] = x;
nxt[cnt] = h[geth(x)];
h[geth(x)] = cnt;
}
int count(int x) {
int hs = geth(x);
int ans = 0;
for(rg int i = h[hs]; i; i = nxt[i]) {
if(v[i] == x) ans++;
}
return ans;
}
}hash;
int main() {
//RS();
n = read(), m = read();
Rep(i, 1, n) a[i] = read();
Rep(i, 1, m) b[i] = read();
Rep(i, 1, m) hash.insert(b[i]);
Rep(i, 0, 29)
Rep(j, i + 1, 29) {
int k = (1 << i) | (1 << j);
Rep(l, 1, n)
ans += hash.count(k ^ a[l]);
}
writeln(ans);
return 0;
}
const int MAXN = 100005;
const int BASE = 29928197;
int n, m;
int a[MAXN], b[MAXN];
struct Hash_Table {
struct Node {
int v, nxt, num;
}h[MAXN * 35];
int head[BASE], cnt;
int getpos(int x) {
return x % BASE;
}
void insert(int x) {
int pos = getpos(x);
for(rg int i = head[pos]; i; i = h[i].nxt) {
if(h[i].v == x) {
h[i].num++;
return;
}
}
h[++cnt].v = x;
h[cnt].num = 1;
h[cnt].nxt = head[pos];
head[pos] = cnt;
}
int query(int x) {
int pos = getpos(x);
int ans = 0;
for(rg int i = head[pos]; i; i = h[i].nxt)
if(h[i].v == x) ans += h[i].num;
return ans;
}
}hash1, hash2;
ll equ, ans;
int main() {
//RS();
n = read(); m = read();
for(rg int i = 1; i <= n; i++) a[i] = read(), hash2.insert(a[i]);
for(rg int i = 1; i <= m; i++) b[i] = read();
for(rg int i = 0; i <= 29; i++)
for(rg int j = 1; j <= n; j++)
hash1.insert(a[j] ^ (1 << i));
for(rg int i = 0; i <= 29; i++)
for(rg int j = 1; j <= m; j++)
ans += hash1.query(b[j] ^ (1 << i));
for(rg int i = 1; i <= m; i++) equ += hash2.query(b[i]);
writeln((ans - equ * 30) >> 1);
return 0;
}
真是一道毒瘤题。。。真是一道毒瘤题。
打完了这道题,你对二维前缀和就应该有深刻的理解了。。。
const int MAXN = 1005;
const int MAXK = 3e5 + 5;
const int MAXS = 30;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
int n, m, k, s;
char a[MAXN][MAXN];
int xl[MAXK], yl[MAXK], xr[MAXK], yr[MAXK];
int cl[MAXK];
ll cnt[MAXN][MAXN], ccnt[MAXN][MAXN][MAXS];
ll f[MAXN][MAXN];
ll ans = INF, id;
ll calc(int x1, int y1, int x2, int y2, int c) {
ll ret = f[n][m] - (f[x2][y2] - f[x1 - 1][y2] - f[x2][y1 - 1] + f[x1 - 1][y1 - 1]);
Rep(i, 0, s - 1) {
ret += Abs(c - i) * (ccnt[x2][y2][i] - ccnt[x1 - 1][y2][i] - ccnt[x2][y1 - 1][i] + ccnt[x1 - 1][y1 - 1][i]);
}
return ret;
}
int main() {
//RS();
n = read(), m = read(), k = read(), s = read();
Rep(i, 1, n) {
scanf("%s", a[i] + 1);
Rep(j, 1, m) a[i][j] -= 'a';
}
Rep(i, 1, k) {
xl[i] = read(), yl[i] = read(), xr[i] = read(), yr[i] = read(), cl[i] = readc() - 'a';
cnt[xl[i]][yl[i]]++, cnt[xr[i]+1][yr[i]+1]++, cnt[xl[i]][yr[i]+1]--, cnt[xr[i]+1][yl[i]]--;
ccnt[xl[i]][yl[i]][cl[i]]++, ccnt[xr[i]+1][yr[i]+1][cl[i]]++, ccnt[xl[i]][yr[i]+1][cl[i]]--, ccnt[xr[i]+1][yl[i]][cl[i]]--;
}
Rep(i, 1, n)
Rep(j, 1, m) {
cnt[i][j] += cnt[i - 1][j] + cnt[i][j - 1] - cnt[i - 1][j - 1];
Rep(l, 0, s - 1)
ccnt[i][j][l] += ccnt[i - 1][j][l] + ccnt[i][j - 1][l] - ccnt[i - 1][j - 1][l];
}
Rep(i, 1, n)
Rep(j, 1, m)
ccnt[i][j][a[i][j]] += k - cnt[i][j];
Rep(i, 1, n)
Rep(j, 1, m) {
f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
Rep(l, 0, s - 1)
f[i][j] += Abs(l - a[i][j]) * ccnt[i][j][l];
}
Rep(i, 1, n)
Rep(j, 1, m)
Rep(l, 0, s - 1)
ccnt[i][j][l] += ccnt[i - 1][j][l] + ccnt[i][j - 1][l] - ccnt[i - 1][j - 1][l];
Rep(i, 1, k) {
ll ret = calc(xl[i], yl[i], xr[i], yr[i], cl[i]);
if(ret < ans) {
ans = ret;
id = i;
}
}
writesp(ans), writeln(id);
return 0;
}