Author : Dipu Kumar Mohanto
CSE, Batch - 6
BRUR.
Problem Statement : Pairwise AND sum
Source : Codechef
Category : Linear Algebra
Algorithm : Fast Walsh-Hadamard transform
Verdict : Accepted
- #include <bits/stdc++.h>
-
- using namespace std;
-
- #define ll long long
-
- static const int MAXN = 1e5 + 5;
- static const int N = 1<<20;
-
- template <typename T> struct FWT
- {
- void fwt(T io[], int n)
- {
- for (int d = 1; d < n; d <<= 1)
- {
- for (int i = 0, m = d<<1; i < n; i += m)
- {
- for (int j = 0; j < d; j++)
- {
- T x = io[i+j], y = io[i+j+d];
- io[i+j] = x+y;
- }
- }
- }
- }
- void ufwt(T io[], int n)
- {
- for (int d = 1; d < n; d <<= 1)
- {
- for (int i = 0, m = d<<1; i < n; i += m)
- {
- for (int j = 0; j < d; j++)
- {
- T x = io[i+j], y = io[i+j+d];
- io[i+j] = x-y;
- }
- }
- }
- }
- void self_convolution(T a[], int n)
- {
- fwt(a, n);
- for (int i = 0; i < n; i++) a[i] = a[i] * a[i];
- ufwt(a, n);
- }
- };
-
-
- ll bruteforce(ll a[], int n)
- {
- ll sum = 0;
- for (int i = 0; i < n; i++)
- {
- for (int j = i+1; j < n; j++)
- {
- sum += a[i] & a[j];
- }
- }
- return sum;
- }
-
- FWT <ll> fwt;
- ll ret[N+5], cnt[N+5];
- ll arr[MAXN];
-
- int main()
- {
-
-
- int n;
- scanf("%d", &n);
- for (int i = 0; i < n; i++)
- {
- scanf("%lld", &arr[i]);
- }
- if (n <= 1000)
- {
- printf("%lld\n", bruteforce(arr, n));
- return 0;
- }
- for (int i = 0; i < n; i++)
- ret[ arr[i] ]++, cnt[ arr[i] ]++;
-
- fwt.self_convolution(ret, N);
- ll sum = 0;
- for (int i = 1; i < N; i++)
- sum += ((ret[i] - cnt[i])>>1)*i;
- printf("%lld\n", sum);
- }
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.