传送门


数论题\(n \leq 500\)肯定是什么暴力算法……

注意到每一个数\(> \sqrt{n}\)的因子最多只有一个,这意味着\(> \sqrt{n}\)的因子之间是独立的,而只有\(\leq \sqrt{n}\)的因子之间会相互影响。而\(\leq \sqrt{n}\)的因子只有\(2,3,5,7,11,13,17,19\)总共\(8\)个,所以可以大力状压。

将\(2-n\)之间的所有数质因数分解,记录其中\(<\sqrt{n}\)的因子的出现情况,按照\(> \sqrt{n}\)的因子分类,一组一组地加入并DP。设\(dp_{i,j,k}\)表示第一个人拥有的寿司中\(<\sqrt{n}\)的因子存在情况为\(i\),第二个人拥有的寿司中\(<\sqrt{n}\)的因子存在情况为\(j\),当前计算的\(> \sqrt{n}\)的因子的存在情况为\(k\)时的方案数,转移看当前寿司分给第一个人还是第二个人。没有\(> \sqrt{n}\)因子的数先单独做一次。

总复杂度\(O(3^8n)\)

#include<iostream>
#include<cstdio>
#include<vector>
//This code is written by Itst
using namespace std;

#define int long long
const int prm[] = {2,3,5,7,11,13,17,19};
int dp[1 << 8][1 << 8][3] , N , MOD;
vector < int > Max[507];

signed main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    //freopen("out","w",stdout);
#endif
    cin >> N >> MOD;
    for(int i = 2 ; i <= N ; ++i){
        int all = 0 , x = i;
        for(int j = 7 ; j >= 0 ; --j){
            all <<= 1;
            if(x % prm[j] == 0){
                while(x % prm[j] == 0)
                    x /= prm[j];
                ++all;
            }
        }
        Max[x].push_back(all);
    }
    dp[0][0][0] = 1;
    for(auto t : Max[1])
        for(int i = (1 << 8) - 1 ; i >= 0 ; --i){
            int s = ((1 << 8) - 1) ^ i , k = s;
            while(1){
                if(!(i & t))
                    dp[i][k | t][0] = (dp[i][k | t][0] + dp[i][k][0]) % MOD;
                if(!(k & t))
                    dp[i | t][k][0] = (dp[i | t][k][0] + dp[i][k][0]) % MOD;
                if(!k) break;
                k = (k - 1) & s;
            }
        }
    for(int p = 2 ; p <= N ; ++p)
        if(!Max[p].empty()){
            for(auto t : Max[p]){
                for(int i = (1 << 8) - 1 ; i >= 0 ; --i){
                    int s = ((1 << 8) - 1) ^ i , k = s;
                    while(1){
                        if(!(i & t))
                            dp[i][k | t][1] = (dp[i][k | t][1] + dp[i][k][0] + dp[i][k][1]) % MOD;
                        if(!(k & t))
                            dp[i | t][k][2] = (dp[i | t][k][2] + dp[i][k][0] + dp[i][k][2]) % MOD;
                        if(!k) break;
                        k = (k - 1) & s;
                    }
                }
            }
            for(int i = (1 << 8) - 1 ; i >= 0 ; --i){
                int s = ((1 << 8) - 1) ^ i , k = s;
                while(1){
                    dp[i][k][0] = (dp[i][k][0] + dp[i][k][1] + dp[i][k][2]) % MOD;
                    dp[i][k][1] = dp[i][k][2] = 0;
                    if(!k) break;
                    k = (k - 1) & s;
                }
            }
        }
    int sum = 0;
    for(int i = (1 << 8) - 1 ; i >= 0 ; --i){
        int s = ((1 << 8) - 1) ^ i , k = s;
        while(1){
            sum = (sum + dp[i][k][0]) % MOD;
            if(!k) break;
            k = (k - 1) & s;
        }
    }
    cout << sum;
    return 0;
}

UOJ129 NOI2015 寿司晚宴 数论、状压DP的更多相关文章

  1. UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)

    题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...

  2. [NOI2015]寿司晚宴(状压dp)

    为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴.小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿司,编号1,2,3,⋯,n-1,其中第种 ...

  3. bzoj 4197: [Noi2015]寿司晚宴【状压dp】

    一个数内可能多个的质因数只有小于根号n的,500内这样的数只有8个,所以考虑状压 把2~n的数处理出小于根号500的质因数集压成s,以及大质数p(没有就是1),然后按p排序 根据题目要求,拥有一个质因 ...

  4. BZOJ4197 [Noi2015]寿司晚宴 【状压dp】

    题目链接 BZOJ4197 题解 两个人选的数都互质,意味着两个人选择了没有交集的质因子集合 容易想到将两个人所选的质因子集合作为状态\(dp\) \(n\)以内质数很多,但容易发现\(\sqrt{n ...

  5. 【Luogu】P2150寿司晚宴(状压DP)

    题目链接 反正……我是没什么想法了,全程看题解 (或者说自己想了半天错解) 因为大于根n的质数最多只会在一个数里出现一种,所以可以把数拆成两部分:小数的二进制集合和大数. 然后把大数一样的放到一起DP ...

  6. 【bzoj4903/uoj300】[CTSC2017]吉夫特 数论+状压dp

    题目描述 给出一个长度为 $n$ 的序列,求所有长度大于等于2的子序列个数,满足:对于子序列中任意两个相邻的数 $a$ 和 $b$ ($a$ 在 $b$ 前面),${a\choose b}\mod 2 ...

  7. BZOJ4197 / UOJ129 [Noi2015]寿司晚宴

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. [NOI2015]寿司晚宴 --- 状压DP

    [NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿 ...

  9. 【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数

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

随机推荐

  1. Azkaban学习之路 (三)Azkaban的使用

    界面介绍 首页有四个菜单 projects:最重要的部分,创建一个工程,所有flows将在工程中运行. scheduling:显示定时任务 executing:显示当前运行的任务 history:显示 ...

  2. jumpserver篇--安装(高可用性 mariadb+haproxy)

    1. 需求 为了解决目前登陆方式多种多样,防火墙配置复杂,历史操作无记录,用户权限混乱等等 2. Jumpserver测试环境搭建 2.1. 环境 os:CentOS release 6.8 mini ...

  3. MVC Scaffolding SmartCode-Engine 更新

    概述 通过扩展visual studio.net scaffolding组件,添加了一套功能完善的代码模板,包括Controller,Model,View,Businessd等各种功能的代码,配合En ...

  4. Linux下如何查看版本

    1.Linux查看版本当前操作系统内核信息 # uname -a   Linux localhost.localdomain 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2 ...

  5. 数据结构(java版)学习笔记(序章)

    程序=数据结构+算法 序章做一个简单的思维导图,方便理解数据结构这门课的大纲,接下来我们将是按照线性表,栈,队列,串,树和图的顺序依次往下学.

  6. es6 Symbol类型

    es6 新增了一个原始类型Symbol,代表独一无二的数据 javascript 原来有6中基本类型, Boolean ,String ,Object,Number, null , undefined ...

  7. 【20190405】JavaScript-正则式匹配与替换结果解析

    在正则式的应用中有三个函数使用得最多:exec().test()与字符串的replace(reg, options).其中test()最简单,只要字符串与正则式可以匹配,就返回true,否则返回fal ...

  8. 广州.NET微软技术俱乐部 - 新秀计划

    本文正在写草稿中, 发布时会在群里单独通知

  9. 超级强大的socket工具ss,替代netstat

    1.结论:ss 命令比netstat 更强大,提供功能更多,并且性能更高. 2.显示当前系统的socket占用总体宏观情况. ss -s 当已创建的socket数过多时,已经说明系统配置存在问题. 3 ...

  10. CPP笔记_函数返回局部变量

    本篇笔记记录的是关于返回函数中的局部值. 我们知道,在函数中创建的局部变量会随着函数的调用过程的结束,也即其对应函数栈帧的清除,而结束其生命周期.那么,如果我们把这个局部变量返回,就有可能存在该变量对 ...