bzoj2734 集合选数

2023-11-02 11:32
文章标签 集合 bzoj2734 选数

本文主要是介绍bzoj2734 集合选数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

集合选数

题目背景:

bzoj2734

分析:构造 + 状态压缩DP

表示思路比较清奇啊·····我是没有想到的······我们来考虑如何选择可行的数字,先构造一个矩阵

1   3   9   27   81   243
2   6   18  54   162  486
4   12  36  108  324  972
8   24  72  216  648  1944
16  48  144 432  1296 3888
...

显然我们可以发现这个矩阵中,相邻的数字(上下或者左右)是都不能被选择的,然后每一行做多只会有11个数,那么我们可以选择直接状压每一行然后DP方案数即可,但是我们可以发现,上面这个矩阵中有些数字是没有出现的,出现的为2m3n形式,那么说明我们的矩阵左上角不一定只能为1,还可以为很多其他的数字,例如5,7,稍加分析就可以知道每一次取在之前的矩阵中没有出现过的最小的数字构造新的矩阵就可以了,并且,这样选择的数字,不同的矩阵中不会出现相同的数(质因子不同)所以直接利用乘法原理相乘即可。

Source

/*created by scarlyw
*/
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <cctype>
#include <vector>
#include <set>
#include <queue>inline char read() {static const int IN_LEN = 1024 * 1024;static char buf[IN_LEN], *s, *t;if (s == t) {t = (s = buf) + fread(buf, 1, IN_LEN, stdin);if (s == t) return -1;}return *s++;
}///*
template<class T>
inline void R(T &x) {static char c;static bool iosig;for (c = read(), iosig = false; !isdigit(c); c = read()) {if (c == -1) return ;if (c == '-') iosig = true;	}for (x = 0; isdigit(c); c = read()) x = ((x << 2) + x << 1) + (c ^ '0');if (iosig) x = -x;
}
//*/const int OUT_LEN = 1024 * 1024;
char obuf[OUT_LEN], *oh = obuf;
inline void write_char(char c) {if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf;*oh++ = c;
}template<class T>
inline void W(T x) {static int buf[30], cnt;if (x == 0) write_char('0');else {if (x < 0) write_char('-'), x = -x;for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48;while (cnt) write_char(buf[cnt--]);}
}inline void flush() {fwrite(obuf, 1, oh - obuf, stdout);
}/*
template<class T>
inline void R(T &x) {static char c;static bool iosig;for (c = getchar(), iosig = false; !isdigit(c); c = getchar())if (c == '-') iosig = true;	for (x = 0; isdigit(c); c = getchar()) x = ((x << 2) + x << 1) + (c ^ '0');if (iosig) x = -x;
}
//*/const int MAXN = 18;
const int mod = 1000000000 + 1;
const int MAXX = 100000 + 10;long long n, ans;
long long matrix[MAXN][MAXN];
long long f[MAXN][1 << MAXN | 1]; 
bool vis[MAXX];inline long long calc(int x) {int r;static int line[MAXN];matrix[1][1] = x, vis[x] = true;for (int i = 1; ; ++i) {if (i != 1) {matrix[i][1] = matrix[i - 1][1] * 2;if (matrix[i][1] > n) {r = i - 1;break ;} else vis[matrix[i][1]] = true;}for (int j = 2; ; ++j) {matrix[i][j] = matrix[i][j - 1] * 3;if (matrix[i][j] > n) {line[i] = j - 1;break ;} else vis[matrix[i][j]] = true;}}line[r + 1] = 0;for (int i = 0; i <= r + 1; ++i)for (int j = 0; j < (1 << line[i]); ++j)f[i][j] = 0;f[0][0] = 1;for (int i = 0; i <= r; ++i)for (int j = 0; j < (1 << line[i]); ++j) {if (f[i][j]) {if (j & (j >> 1)) continue ;for (int k = 0; k < (1 << line[i + 1]); ++k) {if (k & j) continue ;f[i + 1][k] = (f[i + 1][k] + f[i][j]) % mod;}}}return f[r + 1][0];
}int main() {R(n), ans = 1;for (int i = 1; i <= n; ++i) if (!vis[i]) ans = ans * calc(i) % mod;std::cout << ans;return 0;
}

这篇关于bzoj2734 集合选数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/330327

相关文章

Java 的ArrayList集合底层实现与最佳实践

《Java的ArrayList集合底层实现与最佳实践》本文主要介绍了Java的ArrayList集合类的核心概念、底层实现、关键成员变量、初始化机制、容量演变、扩容机制、性能分析、核心方法源码解析、... 目录1. 核心概念与底层实现1.1 ArrayList 的本质1.1.1 底层数据结构JDK 1.7

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java JUC并发集合详解之线程安全容器完全攻略

《JavaJUC并发集合详解之线程安全容器完全攻略》Java通过java.util.concurrent(JUC)包提供了一整套线程安全的并发容器,它们不仅是简单的同步包装,更是基于精妙并发算法构建... 目录一、为什么需要JUC并发集合?二、核心并发集合分类与详解三、选型指南:如何选择合适的并发容器?在多

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方