Start Time:2016-11-05 12:00:00 End Time:2016-11-05 17:00:00 Refresh Time:2016-11-06 21:43:46 Private
E -- array
Time Limit:3s Memory Limit:64MByte
Submissions:465Solved:140
DESCRIPTION
2 array is an array, which looks like:
1,2,4,8,16,32,64......1,2,4,8,16,32,64......
a1=1 | ai+1ai=2a1=1 | ai+1ai=2
Give you a number array, and your mission is to get the number of subsequences ,which is 2 array, of it.
Note: 2 array is a finite array.
INPUT
There are multiple test cases.The first line is a number T (
T ≤10T ≤10), which means the number of cases.For each case, two integer
n(1≤n≤105)n(1≤n≤105).The next line contains
nn numbers
ai(1≤ai≤109)ai(1≤ai≤109)
OUTPUT
one line - the number of subsequence which is 2 array.(the answer will
% 109+7% 109+7)
SAMPLE INPUT
241 2 1 241 2 4 4
SAMPLE OUTPUT
54
没想到DP就直接做了,官方题解:注意到109109范围内的22的幂次只有3030个,所以我们定义dp[30]dp[30]这样一个dp数组,dp[i]dp[i]表示以2i2i为结尾的满足条件的子序列的个数。枚举每一个数来转移,复杂度O(32n)O(32n)。
AC代码:
#include<cstdio>
#include<cstring>
typedef long long LL;
const int MOD=1e9+7;
LL p[44],a[44];
int main()
{
p[1]=1;
for(int i=2;i<=33;++i) {
p[i]=p[i-1]<<1; //printf("%lld %lld\n",i,p[i]);
}
int T; scanf("%d",&T);
while(T--) {
int N; scanf("%d",&N);
memset(a,0,sizeof(a));
for(int i=0;i<N;++i) {
int tem=0;
scanf("%d",&tem);
if(tem==1) {
a[1]=(a[1]+1)%MOD;
continue;
}
for(int j=2;j<33;++j) {
if(tem==p[j]) {
//printf("11111111\n");
a[j]=(a[j]%MOD+a[j-1]%MOD)%MOD;
break;
}
else if(tem<p[j] ) break;
}
}
LL ans=0;
for(int i=1;i<=32;++i) ans=(ans+a[i])%MOD;
printf("%lld\n",ans);
}
return 0;
}