題意:
一個自然數集合
n<=10^9
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#define N 35
#define mmod 1000000007
#define LL long long
using namespace std;
int n,a[N],len,f[N][N][2],ans;
void upd(int &x,int y)
{
x=(x+y)%mmod;
}
void dp()
{
f[1][0][1]=f[1][1][0]=1;
for(int i=1;i<len;i++)
for(int j=0;j<=i;j++)
for(int o=0;o<=1;o++)
{
if(f[i][j][o]==0) continue;
if(a[i+1]==1 || o==1)
upd(f[i+1][j+1][o],f[i][j][o]);
if(o) upd(f[i+1][j][o],(LL)f[i][j][o]*(1ll<<j)%mmod);
else
{
upd(f[i+1][j][0],(LL)f[i][j][0]*(1ll<<(j-1))%mmod);
if(a[i+1]) upd(f[i+1][j][1],(LL)f[i][j][0]*(1ll<<(j-1))%mmod);
}
}
}
int main()
{
scanf("%d",&n);
if(n==0) {printf("1\n");return 0;}
int t=n;
while(t) {a[++len]=t%2;t/=2;}
for(int i=1;i<=len/2;i++) swap(a[i],a[len-i+1]);
dp();
for(int i=0;i<=len;i++)
for(int j=0;j<=1;j++)
upd(ans,f[len][i][j]);
printf("%d\n",ans);
return 0;
}
題解:
O__O
每個perfect set都可以找出一組基是吧。。
用一種奧妙重重的消元方式能使不同的perfect set消出不同且唯一的基(腦補一下吧)。。
於是我們dp那組線性基。。
用心感受一下吧。。