QAQ有一个序列,元素个数有NN个。
他认为一个序列的价值的是:该序列中不同元素之和。
比如说:序列(1,1,2,2)(1,1,2,2)价值为33。
现在QAQ想知道所有子序列的价值之和。QAQ有一个序列,元素个数有NN个。
他认为一个序列的价值的是:该序列中不同元素之和。
比如说:序列(1,1,2,2)(1,1,2,2)价值为33。
现在QAQ想知道所有子序列的价值之和。对每组测试数据,输出一个整数代表所有子序列价值之和。
结果很大,请对(109+7)(109+7)取余。
2
3
1 1 1
4
10 10 10 8
7
204
对于第二组测试数据一共有1515个子序列:
(10)、(10)、(10)、(8)、(10,10)、(10,10)、(10,10)、(10)、(10)、(10)、(8)、(10,10)、(10,10)、(10,10)、
(10,8)、(10,8)、(10,8)、(10,10,8)、(10,10,8)、(10,8)、(10,8)、(10,8)、(10,10,8)、(10,10,8)、
(10,10,8)、(10,10,10)、(10,10,10,8)(10,10,8)、(10,10,10)、(10,10,10,8)。价值之和为204204。
CZY
题解(CZY):
标程应该是这样的,我们用状态压缩的方法记录每个元素的情况。
记num[i]是i元素出现的次数。
然后枚举每一个状态,共有(1<<10) - 1共1023种状态。
对于状态S而言,若出现N个元素,那么它们的组合方案就是
cnt = (2^num[i] - 1) * (2^num[i+1] - 1) * ... *(2^num[N] - 1)。
状态S的贡献就是出现的不同元素和sum 乘上 组合方案cnt。
我们累加贡献即可。
注意1 << x的时候,如果爆int的话,要这样写1LL << x。
AC代码:
#include
#include
typedef long long LL;
const int MOD=1e9+7;
//
//LL Pow_Mod(LL base,LL y,LL MOD)
//{
// LL ans=1;
// while(y) {
// if(y&1) ans=ans*base%MOD;
// y>>=1; base=base*base%MOD;
// }
// return ans;
//}
int main()
{
int a[15],p[55],T,N;
p[0]=1;
for(int i=1;i<=50;++i) p[i]=p[i-1]*2%MOD;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
memset(a,0,sizeof(a));
for(int i=0;i>j)&1) {
times=times*(p[a[j+1]]-1)%MOD;//times溢出 用LL
tota+=j+1;
}
}
ans=(ans+times*tota%MOD)%MOD;
}
printf("%lld\n",ans);
}
return 0;
}