problem in understanding solution?

I’ve attended a contest on codeforces. Here is the [question][1].
solution::

#include <iostream>
#include <cstdio>
#define rep(a,b) for (int a=0;a<b;a++)
using namespace std;

int n,a[1000100],d[1<<22];

int main()
{
	cin >> n;
	rep(i,1<<22) d[i]=-1;
	rep(i,n) scanf("%d",&a[i]), d[a[i]]=a[i];
	rep(i,1<<22) 
		if (d[i]<0)
			rep(j,22)
				if (((i>>j)&1) && d[i^(1<<j)]>=0)
					d[i]=d[i^(1<<j)];
	rep(i,n) printf("%d ",d[(1<<22)-a[i]-1]);
}

But how it is working I’m not able to understand. Need help…!
[1]: http://www.codeforces.com/problemset/problem/165/E

The explanation is here: http://codeforces.com/blog/entry/4124?locale=en