zoukankan      html  css  js  c++  java
  • bzoj 2734: [HNOI2012]集合选数 状压DP

    2734: [HNOI2012]集合选数

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 560  Solved: 321
    [Submit][Status]

    Description

    《集合论与图论》这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中。同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足上述约束条件的子集的个数(只需输出对 1,000,000,001 取模的结果),现在这个问题就 交给你了。 
     

    Input

     只有一行,其中有一个正整数 n,30%的数据满足 n≤20。 
     

    Output


     仅包含一个正整数,表示{1, 2,..., n}有多少个满足上述约束条件 的子集。 
     

    Sample Input


    4

    Sample Output

    8

    【样例解释】
     
    有8 个集合满足要求,分别是空集,{1},{1,4},{2},{2,3},{3},{3,4},{4}。
     
      神奇的排列组合问题,其中分成多个独立子问题,分别转化为矩阵,最有用乘法原理合并的思想可以用在很多题里面。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 100010
    #define MOD 1000000001
    typedef long long qword;
    int gcd(int x,int y)
    {
            return (x%y==0)?y:gcd(y,x%y);
    }
    int pow(int x,int y)
    {
            int ret=1;
            while (y)
            {
                    if (y&1)ret*=x;
                    x*=x;
                    y>>=1;
            }
            return ret;
    }
    qword pow_mod(qword x,int y)
    {
            qword ret=1;
            while(y)
            {
                    if (y&1)ret=ret*x%MOD;
                    x=x*x%MOD;
                    y>>=1;
            }
            return ret;
    }
    int dp[30][1<<12];
    int ff[MAXN];
    int main()
    {
            //freopen("input.txt","r",stdin);
            int n,x,y;
            scanf("%d",&n);
            int i,j,k,ii;
            qword ans=1;
            memset(ff,-1,sizeof(ff));
            for (i=0;i<12;i++)
            {
                    if ((1<<i)<MAXN)
                            ff[(1<<i)]=i;
            }
            for (i=0;i<MAXN;i++)
                    if (ff[i]==-1)ff[i]=ff[i-1];
            for (ii=1;ii<=n;ii++)
            {
                    if (ii%2==0 || ii%3==0)continue;
                    int l,r,mid;
                    l=0,r=12;
                    while (l+1<r)
                    {
                            mid=(l+r)>>1;
                            if ((qword)ii*pow(3,mid)<=n)
                                    l=mid;
                            else
                                    r=mid;
                    }
                    memset(dp,0,sizeof(dp));
                    dp[0][0]=1;
                    x=ii;
                    for (i=1;ii*(1<<i>>1)<=n;i++)//log(n)
                    {
                            for (j=0;j<(1<<r);j++)//2^(log3(n))
                            {
                                    if (!dp[i-1][j])continue;
                                    for (k=0;k<(1<<r);k++)
                                    {
                                            if (j&k || (k&(k<<1)))continue;
                                            if ((qword)x*pow(3,ff[k])>n)break;
                                            dp[i][k]=(dp[i][k]+dp[i-1][j])%MOD;
                                    }
                            }
                            x*=2;
                    }
                    qword res=0;
                    for (j=0;j<(1<<r);j++)
                    {
                            res=(res+dp[i-1][j])%MOD;
                    }
                    ans=ans*res%MOD;
            }
            printf("%lld
    ",ans);
    }
     
     
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    食物链(带权&种类并查集)
    抓屏工具 faststone capture
    ViewerJS 一个在浏览器上查看 PDF 和电子表格的 JavaScript 库
    html中调用本地exe应用程序
    html+css构成的框架,可自行改造
    普通人每天应该睡多长时间??
    利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能)
    解决在IE11浏览器上,css样式不起作用的问题
    Dreamweaver cs6 的安装与破解
    博客生活第一天
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4109898.html
Copyright © 2011-2022 走看看