• BZO4197 & 洛谷2150 & UOJ129:[NOI2015]寿司晚宴——题解


    https://www.lydsy.com/JudgeOnline/problem.php?id=4197

    https://www.luogu.org/problemnew/show/P2150

    http://uoj.ac/problem/129

    为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴。小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴。

    在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 1,2,3,…,n−1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n)。
    现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x 的寿司,小 W 品尝的寿司中存在一种美味度为 y 的寿司,而 x 与 y 不互质。
    现在小 G 和小 W 希望统计一共有多少种和谐的品尝寿司的方案(对给定的正整数 p 取模)。注意一个人可以不吃任何寿司。

    这题的难点就在思维了(然而我就少脑子),只要你想到压位质数的话,这道题就迎刃而解了。

    参考:https://www.luogu.org/blog/larryzhong/solution-p2150

    设f[i][j][k]表示到第i个寿司,G取的寿司的质因子集合为j,W为k。

    不难想到dp的转移方程。

    但是n是<=500的啊,其质数应该会有很多啊我们也压不过来啊。

    考虑到一个数只有一个大于sqrt(n)的质因子,所以我们惊奇的发现,我们只需要压8个小于sqrt(n)的质因子即可,对于那个多出来的质数我们额外考虑就行了。

    我们先对每个数的大因子排个序,则:

    设g[i][0/1][j][k]表示当前处理大因子为i,j有大因子/k有大因子,G取的寿司的质因子集合为j,W为k。

    转移方程基本同f。

    将相同i的数处理完之后再把g放到f里。

    f[j][k]=g[0][j][k]+g[1][j][k]-f[j][k]

    (其中多减掉的那个原因是我们把两个集合都不取大因子i的情况算了两遍。)

    (注意到f和g的第一维都可以省略。)

    那么答案就是j和k不互相包含的f的总和。

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=502;
    const int B=8;
    const int M=1<<B;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct num{
        int a,b;
    }s[N];
    int pri[B]={2,3,5,7,11,13,17,19};
    int n,p,f[M][M],g[2][M][M];
    inline bool cmp(num a,num b){
        return a.b<b.b;
    }
    int main(){
        n=read(),p=read();
        for(int i=2;i<=n;i++){
            int tmp=i;
            for(int j=0;j<B;j++){
                while(tmp%pri[j]==0){
                    tmp/=pri[j];
                    s[i].a|=(1<<j);
                }
            }
            if(tmp>1)s[i].b=tmp;
        }
        sort(s+2,s+n+1,cmp);
        f[0][0]=1;
        for(int i=2;i<=n;i++){
            if(i==2||(!s[i].b)||s[i].b!=s[i-1].b){
                memcpy(g[0],f,sizeof(f));
                memcpy(g[1],f,sizeof(f));
            }
            for(int j=M-1;j>=0;j--){
                for(int k=M-1;k>=0;k--){
                    (g[0][j|s[i].a][k]+=g[0][j][k])%=p;
                    (g[1][j][k|s[i].a]+=g[1][j][k])%=p;
                }
            }
            if(i==n||(!s[i].b)||s[i].b!=s[i+1].b){
                for(int j=M-1;j>=0;j--){
                    for(int k=M-1;k>=0;k--){
                        f[j][k]=((g[0][j][k]+g[1][j][k]-f[j][k])%p+p)%p;
                    }
                }
            }
        }
        int ans=0;
        for(int j=0;j<M;j++){
            for(int k=0;k<M;k++){
                if(!(j&k))(ans+=f[j][k])%=p;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    毕设计划(一)
    上传整个项目或者文件夹到github
    分布式架构中数据一致性常见的几个问题(云时代架构文章读后感16)
    关于技术规划、管理、架构的思考(云时代架构文章读后感15)
    互联网高新吗(云时代架构文章读后感14)
    第三方支付账务系统设计难点(云时代架构文章读后感13)
    关于SOA的理解
    系统架构师(云时代架构文章读后感12)
    会话管理(云时代架构文章读后感11)
    【sklearn第二讲】scikit-learn 方法一览图
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9136448.html
Copyright © 2020-2023  润新知