zoukankan      html  css  js  c++  java
  • bzoj4197

    这题现场想的思路方向都是对的,但限于现场和实力因素没能A

    很显然我们会想到质因数的选取

    如果某个质数p被W选了,那G就不能选含有质因子p的数

    因此我们不难想到状压质数的选取情况,令f[i][j]为w质数选取状态为i,g质数选取状态j的方案数

    但是500以内质数太多了怎么办?我们考虑大质数能不能分开考虑

    考虑到sqrt(500)以外的质数,他们在每个数中最多出现一次,因此我们只要按这些质数分类做dp即可

    这样需要状压的质数只有2,3,5,7,11,13,17,23这8个了,这样就可以解决了

    具体的,我用state表示每个数前8个质数的含有情况,res表示除去前8个质数剩下的数

    然后按照res排序做dp即可

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<stdlib.h>
     6 #include<algorithm>
     7 
     8 using namespace std;
     9 const int sp[8]={2,3,5,7,11,13,17,19};
    10 struct node{int res,st;} a[510];
    11 
    12 int f[256][256],g[2][256][256];
    13 int ans,n,p;
    14 bool cmp(node a,node b)
    15 {
    16      return a.res<b.res;
    17 }
    18 int main()
    19 {
    20     scanf("%d%d",&n,&p);
    21     for (int i=2; i<=n; i++)
    22     {
    23         int x=i;
    24         for (int j=0; j<8; j++)
    25           if (x%sp[j]==0)
    26           {
    27              a[i].st+=1<<j;
    28              while (x%sp[j]==0) x/=sp[j];
    29           } 
    30         a[i].res=x;
    31     }  
    32     sort(a+2,a+1+n,cmp);
    33     f[0][0]=g[0][0][0]=g[1][0][0]=1;
    34     for (int i=2; i<=n; i++)
    35     { 
    36         memcpy(g[0],f,sizeof(f));
    37         memcpy(g[1],f,sizeof(f));
    38         for (int u=0; u<256; u++)
    39           for (int v=0; v<256; v++)
    40             if ((u&v)==0)
    41             {
    42                 if ((a[i].st&v)==0) g[0][u|a[i].st][v]=(g[0][u|a[i].st][v]+f[u][v])%p;
    43                 if ((a[i].st&u)==0) g[1][u][v|a[i].st]=(g[1][u][v|a[i].st]+f[u][v])%p;             
    44             }
    45         
    46         if (a[i].res!=1)
    47         {
    48            int j;
    49            for (j=i+1; j<=n&&a[j].res==a[i].res; j++)
    50              for (int u=255;u>=0;u--)
    51                for (int v=255;v>=0;v--)
    52                  if ((u&v)==0)
    53                  {
    54                     if ((a[j].st&v)==0) g[0][u|a[j].st][v]=(g[0][u|a[j].st][v]+g[0][u][v])%p;
    55                     if ((a[j].st&u)==0) g[1][u][v|a[j].st]=(g[1][u][v|a[j].st]+g[1][u][v])%p;             
    56                  }        
    57            i=j-1;
    58         }
    59         for (int u=0; u<256; u++)
    60           for (int v=0; v<256; v++)
    61             f[u][v]=((g[0][u][v]+g[1][u][v]-f[u][v])%p+p)%p;
    62     }
    63     for (int i=0; i<=255; i++)
    64       for (int j=0; j<=255; j++)
    65         if ((i&j)==0) ans=(ans+f[i][j])%p;
    66     printf("%d
    ",ans);
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    JSONObject和JSONArray区别及基本用法
    MySQL中UTF8编码的数据在cmd下乱码
    js页面刷新跳转的几种方式及区别
    JS中使用EL表达式
    $.ajax()方法参数详解
    Firefox默认英文修改中文
    配置文件的相对地址和绝对地址设置
    IntelliJ IDEA设置统一编码utf-8
    java.lang.SecurityException: Prohibited package name:
    flask的多个url对应同一个视图函数
  • 原文地址:https://www.cnblogs.com/phile/p/5658530.html
Copyright © 2011-2022 走看看