Infinite Set (CF2D) (二进制+dp处理)

 

 思路:

  • 给出了, 2^p, 然后2x+1, 4x, 发现和二有关
  • 进一步, 2x+1 是在 后面加一位 1, 4x, 是在后面+ 00; 
  • 因此直接dp处理
  • 对于本身的a[i], 看有没有数能够更新他即可. -> 有1去1, 有00 去00, 即可
#include <bits/stdc++.h>
using namespace std;
#define ri register int 
#define M 2000005

int n,m;
int p[M];
map<int,int> mp;
vector<int> pp[50];
long long dp[M];
int mod = 1e9+7;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    cin>>n>>m;
    for(ri i=1;i<=n;i++)
    {
        cin>>p[i];
    }
    for(ri i=1;i<=n;i++)
    {
        for(ri j=1;j<=34;j++)
        {
            long long tmp=1;
            if((tmp<<(j-1))>p[i])
            {
                pp[j-1].push_back(p[i]);    
            //    cout<<j-1<<" "<<p[i]<<"\n";
                break;
            }
        }
    }
    for(ri i=1;i<=m;i++)
    {
        if(i<=32)
        for(ri j=0;j<pp[i].size();j++)
        {
            int a=pp[i][j];
            int flag=1;
            while(a)
            {
                if(mp[a])
                {
                    flag=0;break;
                }
                if(a&1) a>>=1;
                else
                {
                    if((a/2)&1) break;
                    else a>>=2;
                }
            }
            if(flag) dp[i]++;
            mp[pp[i][j]]=1;
        }

        if(i-2>=0) dp[i]=(dp[i]+dp[i-2])%mod;
        if(i-1>=0) dp[i]=(dp[i]+dp[i-1])%mod;
    }
    long long ans=0;
    for(ri i=1;i<=m;i++)
    {
        ans=(ans+dp[i])%mod;
    //    cout<<dp[i]<<" ";
    }
    cout<<ans;
    return 0;

}
View Code

 

posted @ 2022-11-21 11:32  VxiaohuanV  阅读(21)  评论(0编辑  收藏  举报