寿司晚宴

#include<bits/stdc++.h>
using namespace std;
const int N=500+5;
typedef long long ll;
int n,mod;
int pri[8]={2,3,5,7,11,13,17,19};
int zh[N],cnt;//fen jie
int ps[N],tot;
int vis[N];
int has[N];//binary number
void sieve(){
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            tot++;ps[tot]=i;
            vis[i]=i;
        }
        for(int j=1;j<=tot;j++){
            if(i*ps[j]>n) break;
            vis[i*ps[j]]=ps[j];
            if(i%ps[j]==0) break;
        }
    }
}
vector<int>mem[N];//i th big prime's members
void sol(int x){
    cnt=0;
    int kk=x;
    for(int i=1;i<=tot;i++){
        if(x%ps[i]==0){
            zh[++cnt]=i;//prime's id
            while(x%ps[i]==0) x/=ps[i];
        }
    }
    for(int i=1;i<=cnt;i++){
        if(zh[i]>8) mem[zh[i]].push_back(kk);
        else has[kk]|=(1<<i-1);
    }
}// has little primes
int f[96][1<<8][1<<8];//has covered first i th prime
int g[30][1<<8][1<<8];
int t1[30][1<<8],t2[30][1<<8];//////////////////////////////////////////////warning!!! a int !!!!
ll ans;
int main()
{
    scanf("%d%d",&n,&mod);
    sieve();
    
    //cout<<tot<<endl;
    
    for(int i=2;i<=n;i++) sol(i);
    g[1][0][0]=1;
    
    for(int i=1;i<=min(22,n)-1;i++){
      for(int j=0;j<=(1<<8)-1;j++)
        for(int k=0;k<=(1<<8)-1;k++){
            g[i+1][j|has[i]][k]=(g[i+1][j|has[i]][k]+g[i][j][k])%mod;
            g[i+1][j][k|has[i]]=(g[i+1][j][k|has[i]]+g[i][j][k])%mod;
            g[i+1][j][k]=(g[i+1][j][k]+g[i][j][k])%mod;     
        }
    }
    
    if(n<23){
        int las=0;
        for(int i=1;i<=8;i++){
            if(ps[i]>n) break;
            las=i;
        }
        for(int j=0;j<=(1<<las)-1;j++)    
         for(int k=0;k<=(1<<las)-1;k++){
             if((j&k)==0) ans=(ans+g[n][j][k])%mod;
         }
        printf("%d",ans);
        return 0;
    }
    f[8][0][0]=1;
    for(int i=8;i<tot&&ps[i+1]<=n;i++){
        memset(t1,0,sizeof t1);
        memset(t2,0,sizeof t2);
        t1[0][0]=1;t2[0][0]=1;
        for(int j=0;j<mem[i+1].size();j++){
          for(int A=0;A<=(1<<8)-1;A++){
            t1[j+1][A|has[mem[i+1][j]]]=(t1[j+1][A|has[mem[i+1][j]]]+t1[j][A])%mod;
            t1[j+1][A]=(t1[j+1][A]+t1[j][A])%mod;
          }
          for(int B=0;B<=(1<<8)-1;B++){
              t2[j+1][B|has[mem[i+1][j]]]=(t2[j+1][B|has[mem[i+1][j]]]+t2[j][B])%mod;
              t2[j+1][B]=(t2[j+1][B]+t2[j][B])%mod;
          }
        }//t1/t2[mem[i+1].size()]
        for(int A=0;A<=(1<<8)-1;A++)
          for(int B=0;B<=(1<<8)-1;B++)
          {    
            
          }
    }
}

猜你喜欢

转载自www.cnblogs.com/Miracevin/p/9342802.html