一个集合的 子集的和的平方 的和 就记一下
∑a0i
、
∑a1i
和
∑a2i
就好了
处理出
f(S)≥x
的 这个就是一个6维前缀和
然后再把前缀和倒回去 就好了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=1000000;
const int P=1e9+7;
const int pw[]={1,10,100,1000,10000,100000,1000000};
inline void add(int &x,int y){
x+=y; if (x>=P) x-=P;
}
int n;
int f[N][3];
int g[N];
int _pow[N+5];
int main(){
int x;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
_pow[0]=1; for (int i=1;i<=N+2;i++) _pow[i]=_pow[i-1]*2%P;
read(n);
for (int i=1;i<=n;i++) read(x),f[x][0]++,add(f[x][1],x),add(f[x][2],(ll)x*x%P);
for (int j=0;j<6;j++)
for (int i=N-1;i;i--)
if (i/pw[j]%10!=9)
for (int t=0;t<3;t++)
add(f[i][t],f[i+pw[j]][t]);
for (int i=0;i<N;i++)
g[i]=((ll)f[i][2]*_pow[f[i][0]-1]%P+((ll)f[i][1]*f[i][1]%P+P-f[i][2])*_pow[f[i][0]-2]%P)%P;
for (int j=0;j<6;j++)
for (int i=0;i<N;i++)
if (i/pw[j]%10!=9)
g[i]=(g[i]+P-g[i+pw[j]])%P;
ll ans=0;
for (int i=0;i<N;i++)
ans^=(ll)g[i]*i;
printf("%lld\n",ans);
return 0;
}