SCU 4424(求子集排列数)

A - A

Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Submit Status Practice SCU 4424

Description

 Time Limit: 1000ms


Description

 Given N distinct elements, how many permutations we can get from all the possible subset of the elements?

Input

 The first line is an integer T that stands for the number of test cases.
Then T line follow and each line is a test case consisted of an integer N.

Constraints:
T is in the range of [0, 10000]
N is in the range of [0, 8000000]

Output

 For each case output the answer modulo 1000000007 in a single line.

Sample Input

 5
0
1
2
3
4

Sample Output

 0
1
4
15
64 题意:给n个不同的数,求子集的排列数分析:做道题竟然没想到是递推,天真的是考求组合数的知识。之后在看到大神讲解焕然大悟以n为例:当子集是1个数时,有n种情况,子集个数是2,就有n*(n-1),子集个数为三,就有n*(n-1)*(n*2)....直到为n时就是 n*(n-1)*(n-2)....1;其实也是在排列组合数把s[n] = n + n*(n-1) + n*(n-1)*(n-2) + .....+n*(n-1)*(n-2)...*1;把n提出来就是s[n] = n*( 1+(n-1)+(n-1)*(n-2) +...... +(n-2)*...*1) = n*(1+s[n-1])

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 using namespace std;
 6 const int mod = 1e9 + 7;
 7 const int MAX = 8000000 + 10;
 8 long long a[MAX];
 9 int main()
10 {
11     a[0] = 0;
12     a[1] = 1;
13     for(int i = 2; i <= MAX; i++)
14     {
15         a[i] = i * ( a[i - 1] + 1) % mod;
16     }
17     int t;
18     scanf("%d", &t);
19     while(t--)
20     {
21         int num;
22         scanf("%d", &num);
23         printf("%lld\n", a[num]);
24     }
25     return 0;
26 }


 
时间: 2024-10-13 21:33:09

SCU 4424(求子集排列数)的相关文章

C语言 &#183; 排列数

算法提高 排列数 时间限制:1.0s   内存限制:256.0MB 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入一个数n 求0~9十个数的全排列中的第n个(第1个为0123456789). 输入格式 一行,包含一个整数n 输出格式 一行,包含一组10个数字的全排列 样例输入 1 样例输出 0123456789 数据规模和约定 0 < n <= 10! 1 #include<stdio.h> 2 #includ

求数组排列的范围

问题描述:给定一个整数数组,将这个整数数组排列成一个整数,并且数组的每个元素都要用到,求所排列出的整数的范围. 分析:这是一个很有意思的题目,初看好像是要求所有排列情况的最小值和最大值,当然这样做也可以求出来,只不过时间复杂度过高, 另外还有一个问题是大数问题,所排列成的数可能范围很大,超过了基本数据类型所能表示的范围,因此需要转换为字符串处理. 下面详细介绍解法: 解法一:用排列法.也就是求出这个数组的全排列,然后求出这个排列的最小值和最大值.由于排列要用到递归实现, 递归一般消耗系统大量的时

第k个排列数

变长编码,这里排列的序号是0到n!-1,假设求 1,2,3,4 的第15个排列数,15/(3!) = 2, 余数是3,第一个数是(1,2,3,4)中的第二个数 3 (这里0是开始位置),3/(2!) = 1, 余数是1,第二个数就是(1,2,4)中的第一个数 2,  1/(1!) = 1, 余数是0,第三个数(1,4)中的第1个数就是4, 最后一个数就是1.结果就是3,2,4,1 #include <cstdio>#include <cstring>#include <vec

C语言 &#183; 排列数 &#183; 排列式

蓝桥练习场上不断碰到类似的题,都是一个递归搜索的套路. 算法提高 排列数 时间限制:1.0s   内存限制:256.0MB 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入一个数n 求0~9十个数的全排列中的第n个(第1个为0123456789). 输入格式 一行,包含一个整数n 输出格式 一行,包含一组10个数字的全排列 样例输入 1 样例输出 0123456789 数据规模和约定 0 < n <= 10! 作者注释:标准

分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)

思路: 分治法 归并排序的过程中,有一步是从左右两个数组中,每次都取出小的那个元素放到tmp[]数组中 右边的数组其实就是原数组中位于右侧的元素.当不取左侧的元素而取右侧的元素时,说明左侧剩下的元素均比右侧的第一个元素大,即均能构成一个逆序对.假设现在左侧剩余n个元素,则逆序对数+n. 另外,如果当所有右侧的元素都取完,但是左侧仍然有元素剩余时,左侧剩余的元素已经在之前的运算中加到了逆序对中,不需要再添加一次 下面给出 归并排序 和 求逆序对数 两份代码: code1: 归并排序 #includ

分页过滤SQL求总条数SQL正则

public static void main(String[] args) throws Exception { String queryForScanUsers_SQL = "select a.username AS user_name,b.* from tbl_aaa a left join tbl_bbb b where a.id=? limit 10"; //去除WHERE和LIMIT String sqlRegex = "(select\\s+)(.*)(\\s+

如何直观地理解排列数和组合数

如果要问我高中时学文科有什么不好,我觉得,最不好的一点就是在你上概率论课时,你听着老师讲的内容一脸蒙蔽,而其他同学纷纷表示自己高中时就已经学过了.之前做题遇到排列数与组合数都是直接写A和C,并不进行计算,所以对于其公式也只是记住能用就好,但是今天闲着无聊,想试着推导一下排列数和组合数的公式,也为了能深入理解排列数和组合数的原理,所以就开始了天马行空的想象. 对于排列数,可以视为“分步解决”的问题,也就是说: 第一步,从n个某物中选取1个,有n种选择方法: 第二步,从剩下的n-1个某物中选取1个,

【C语言】不使用大小于号,求出两数最大值

//不使用大小于号,求出两数最大值 #include <stdio.h> #include <math.h> double Max(double a, double b) { double q = sqrt((a-b)*(a-b)); return ((a + b) + q) / 2; } int main() { printf("(5,8)大的数为:%.0f\n", Max(5, 8)); printf("(0,4)大的数为:%.0f\n"

java-第七章-数组-求出一些数的最小值

import java.util.Scanner; public class A04 { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); double[] Price = new double[4]; double min = 0; System.out.println("请输入4家店的价格"); for