Description

windy学会了一种游戏。对于1到N这N个数字,都有唯一 且不同的1到N的数字与之对应。最开始windy把数字按顺序1,2,3,……,N写一排在纸上。然后再在这一排下面写上它们对应的数字。然后又在新的一 排下面写上它们对应的数字。如此反复,直到序列再次变为1,2,3,……,N。 如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6->6 windy的操作如下 1 2 3 4 5 6 2 3 1 5 4 6 3 1 2 4 5 6 1 2 3 5 4 6 2 3 1 4 5 6 3 1 2 5 4 6 1 2 3 4 5 6 这时,我们就有若干排1到N的排列,上例中有7排。现在windy想知道,对于所有可能的对应关系,有多少种可能的排数。

Input

包含一个整数,N。

Output

包含一个整数,可能的排数。

Sample Input

【输入样例一】
3
【输入样例二】
10

Sample Output

【输出样例一】
3
【输出样例二】
16

HINT

【数据规模和约定】

100%的数据,满足 1 <= N <= 1000 。

分析

     要用到一点点群论的知识:一个置换可以分解成若干个不相交循环的乘积,且这个置换的阶数就等于各个循环的元素个数的最小公倍数。

那么我们要考虑的问题变成了:将N划分成若干个整数的和,这些整数的最小公倍数共有多少种取值?

先考虑一个整数的唯一分解$M=\prod {p_i} ^ {a_i}$,如果它在答案中,则$S = \sum {p_i} ^ {a_i}$一定在N以内。因为对于一个不大于N的整数的任何一个满足最大公约数大于1的整数划分,我们将每个整数中重复的质因子除去,得到的一组两两互质的整数,它们的和也一定不大于N,且它们的最小公倍数不变。因此我们只需计算出N以内这些两两互质的整数划分的方案树就可以了。简单来说,就是“要用一个整数划分凑出某个确定的最小公倍数,最‘节约’的方案是用这个最小公倍数的唯一分解”。

具体地,我们可以先筛出N以内的所有素数,对于每种素数只能选择其中的一个幂次乘入答案,求一下分组背包就可以了。

 1 /**************************************************************
 2     Problem: 1025
 3     User: AsmDef
 4     Language: C++
 5     Result: Accepted
 6     Time:4 ms
 7     Memory:824 kb
 8 ****************************************************************/
 9  
 /***********************************************************************/
 /**********************By Asm.Def-Wu Jiaxin*****************************/
 /***********************************************************************/
 #include <cstdio>
 #include <cstring>
 #include <cstdlib>
 #include <ctime>
 #include <cctype>
 #include <algorithm>
 #include <cmath>
 using namespace std;
 typedef long long LL;
 #define SetFile(x) ( freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout) )
 #define getc() getchar()
 template<class T>inline void getd(T &x){
     char ch = getc();bool neg = false;
     while(!isdigit(ch) && ch != '-')ch = getc();
     if(ch == '-')ch = getc(), neg = true;
     x = ch - ';
      - ' + ch;
     if(neg)x = -x;
 }
 inline void putLL(LL x){
     ){printf("%d\n", x);return;}
     , r = x % ;
     printf("%d%09d\n", l, r);
 }
 /***********************************************************************/
 ;
 int prime[maxn], pcnt, N;
 LL F[maxn], tmp[maxn];
 inline void euler(){
     };
     int i, j;
     ;i <= N;++i){
         if(!not_p[i])prime[++pcnt] = i;
         ;j <= pcnt;++j){
             if(i * prime[j] > N)break;
             not_p[i * prime[j]] = true;
             )break;
         }
     }
 }
  
 inline void work(){
     getd(N);
     euler();
     //for(int i = 1;i <= pcnt;++i)printf("%d\n", prime[i]);
     int i, j, p, d;
     LL ans = ;
     F[] = ;
     ;i <= pcnt;++i){
         p = prime[i];
         memcpy(tmp, F, sizeof(F));
         for(d = p;d <= N;d *= p)
             for(j = d;j <= N;++j)F[j] += tmp[j-d];
     }
     ;i <= N;++i) ans += F[i];
     putLL(ans);
 }
  
 int main(){
  
 #ifdef DEBUG
     freopen("test.txt", "r", stdin);
 #elif !defined ONLINE_JUDGE
     //SetFile(bzoj_1025);
 #endif
     work();
  
 #ifdef DEBUG
     //printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
 #endif
     ;
 }

分组背包

[bzoj1025][SCOI2009]游戏 (分组背包)的更多相关文章

  1. bzoj千题计划116:bzoj1025: [SCOI2009]游戏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题目转化: 将n分为任意段,设每段的长度分别为x1,x2,…… 求lcm(xi)的个数 有一个 ...

  2. BZOJ 1025 游戏(分组背包)

    题目所谓的序列长度实际上就是各循环节的lcm+1. 所以题目等价于求出 一串数之和等于n,这串数的lcm种数. 由唯一分解定理可以联想到只要把每个素数的幂次放在一个分组里,然后对整体做一遍分组背包就行 ...

  3. BZOJ1025 [SCOI2009]游戏 【置换群 + 背包dp】

    题目链接 BZOJ1025 题解 题意就是问一个\(1....n\)的排列在同一个置换不断重复下回到\(1...n\)可能需要的次数的个数 和置换群也没太大关系 我们只需知道同一个置换不断重复,实际上 ...

  4. [BZOJ1025] [SCOI2009]游戏 解题报告

    Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对 ...

  5. BZOJ1025: [SCOI2009]游戏

    Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对 ...

  6. 2018.09.02 bzoj1025: [SCOI2009]游戏(计数dp+线筛预处理)

    传送门 要将所有置换变成一个轮换,显然轮换的周期是所有置换长度的最小公倍数. 于是我们只需要求长度不超过n,且长度最小公倍数为t的不同置换数. 而我们知道,lcm只跟所有素数的最高位有关. 因此lcm ...

  7. [BZOJ1025][SCOI2009]游戏 DP+置换群

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题目中的排数就是多少次回到原来的序列.很显然对于题目所描述的任意一种对应法则,其中一 ...

  8. bzoj1025: [SCOI2009] 游戏 6

    DP. 每种排法的长度对应所有循环节长度的最小公倍数. 所以排法总数为和为n的几个数的最小公倍数的总数. #include<cstdio> #include<algorithm> ...

  9. bzoj1025(SCOI2009)游戏——唯一分解的思路与应用

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1025 可以认为对应的值之间连边,就连成了一个有一个或几个环的图.列数就是每个环里点数的lcm ...

随机推荐

  1. docker 镜像导入和导出

    使用 docker commit 即可把这个容器变为一个镜像 docker commit 8d93082a9ce1 ubuntu:myubuntu 这时候 docker 容器会被创建为一个新的 Ubu ...

  2. thinkphp 5.0 代码执行漏洞

    https://github.com/vulhub/vulhub/blob/master/thinkphp/5-rce docker-compose -f /home/root/compose.yml ...

  3. PHY Linux 驱动

    以太网 MAC(链路层)+PHY(物理层/RTL8201F,88E1111);集成型DM9000,RTL8139CP 由于网络数据传输量较大,不论是分开型还是集成型,通常会在MAC和PHY之间引入DM ...

  4. ubuntu10.04 svn安装方法

    ubuntu10.04 svn安装方法:sudo apt-get install subversion sudo apt-get install libneon27-dev orsudo apt-ge ...

  5. 服务号使用微信网页授权(H5应用等)

    获取授权准备 AppId 服务号已经认证且获取到响应接口权限 设置网页授权域名 公众号设置 - 功能设置 - 网页授权域名.注意事项: 回调页面域名或路径需使用字母.数字及"-"的 ...

  6. C/C++——库函数strcpy和strdup比较

    版权声明:原创文章,禁止转载. 1. strcpy 原型: extern char *strcpy(char *dest,char *src); 用法: #include <string.h&g ...

  7. 模块定义文件.def

    一作用 DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport),这里不再举例说明:另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供 ...

  8. Linux下的各类文件

    .a文件是静态链接库文件.所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分.当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源.. ...

  9. Python静态代码检查工具Flake8

    简介 Flake8 是由Python官方发布的一款辅助检测Python代码是否规范的工具,相对于目前热度比较高的Pylint来说,Flake8检查规则灵活,支持集成额外插件,扩展性强.Flake8是对 ...

  10. MINIBASE源代码阅读笔记之heapfile

    Heapfile 用来管理heap file里的dir page们 成员 _firstDirPageId:这个文件的第一个dir page _ftype:文件类型 _file_deleted:删除的时 ...