zoukankan      html  css  js  c++  java
  • dtoj2402. 任性(willful)

     

    俗话说,有钱就是任性。我们的高富帅鱼丸同学打算去看电影。鱼丸到了电影院以后,发现座位的编号正好是 $1$ 到 $200$ 。但是有一些座位号对应的座位坏掉了,没法坐,不妨假设还剩下 $N$ 个能坐的椅子。电影的老板告诉鱼丸,如果你要包下一个集合 $S$ 里的所有椅子,就要付出这些椅子的编号的最小公倍数的钱。鱼丸很任性地同意了。

    来这里玩了很多天以后,鱼丸发现自己正好来了 $2^N-1$ 天,并且由于他非常任性,对于这 $N$ 个椅子的每一种可能的非空子集,他都包下过来看电影。鱼丸大少爷虽然不在乎花了多少钱,但你毕竟是他的助理,于是你想知道鱼丸一共花了多少钱。由于钱的数量实在太大,请对答案 $mod~1e9+7$之后输出


    Sol.

    本题 $ N leq 200 $。

    lcm中指数大于1的只能是2,3,5,7,11,13.

    令f[i][a][b][c][d][e][f]表示前i个数,他们的指数是a,b,c,d,e,f的答案;

    转移时只要看这个数加不加入就行。

    那我们还得加上那些其他的质数。

    我们考虑把那个大质数拉出来排序。

    每次处理含有相同大质数的数。

    那么在f后面多一维[0/1]表示当前处理的大指数是否出现过即可。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define For for(int a=0;a<8;a++)for(int b=0;b<5;b++)for(int c=0;c<4;c++)for(int d=0;d<3;d++)for(int e=0;e<3;e++)for(int f=0;f<3;f++)
    #define S [a][b][c][d][e][f]
    #define ns [max(a,s[i].t[0])][max(b,s[i].t[1])][max(c,s[i].t[2])][max(d,s[i].t[3])][max(e,s[i].t[4])][max(f,s[i].t[5])]
    #define mod 1000000007
    #define ll long long
    using namespace std;
    int n,p[6]={2,3,5,7,11,13},ans;
    ll g[202][8][5][4][3][3][3][2],dp[8][5][4][3][3][3];
    struct node{
        int M,t[6];
    }s[202];
    bool cmp(node A,node B){return A.M<B.M;}
    int w(int a,int num){
        if(num<=0)return 1;
        int A=1;for(;num;num>>=1,a=a*a%mod)if(num&1)A=A*a;return A;
    }
    int calc(int i,int a,int b,int c,int d,int e,int f){
        return w(p[0],s[i].t[0]-a)*w(p[1],s[i].t[1]-b)*w(p[2],s[i].t[2]-c)*w(p[3],s[i].t[3]-d)*w(p[4],s[i].t[4]-e)*w(p[5],s[i].t[5]-f);
    }
    int main(){
        cin>>n;
        for(int i=1,v;i<=n;i++){
            scanf("%d",&v);
            for(int j=0;j<6;j++)while(v%p[j]==0)v/=p[j],s[i].t[j]++;
            s[i].M=v;
        }
        sort(s+1,s+n+1,cmp);
        dp[0][0][0][0][0][0]=1;
        for(int i=1;i<=n;i++){
            if(s[i].M!=s[i-1].M)For g[i-1]S[0]=dp S,g[i-1]S[1]=0; 
            
            For g[i]S[0]=g[i-1]S[0],g[i]S[1]=g[i-1]S[1];
            For{
                (g[i]ns[1]+=g[i-1]S[0]*s[i].M%mod*calc(i,a,b,c,d,e,f)%mod)%=mod;
                if(s[i].M==s[i-1].M)(g[i]ns[1]+=g[i-1]S[1]*calc(i,a,b,c,d,e,f))%=mod;
            }
            if(s[i].M!=s[i+1].M)For dp S= (g[i]S[0]+g[i]S[1])%mod;
        }
        For (ans+=dp S)%=mod;
        cout<<ans-1<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    atitit.颜色查找 根据范围 图像处理 inRange
    Atitit 跨平台的系统截图解决方案
    Atitit java opencv 捕获视频
    路法Atiti
    Atitit 获取本机图像设备视频设备列表 设备检索列表解决方案
    Atitit 团队工具链体系打造提升团队效率的一些通用软件 attilax总结
    Atitit gui控件定位解决方案
    Atitit html5.1 新特性attilax总结
    Atitti 模板匹配 List matchTemplate(
    利用CRebar和CDialogBar编写可浮动的dialog类型的工具栏
  • 原文地址:https://www.cnblogs.com/liankewei/p/12301750.html
Copyright © 2011-2022 走看看