Codeforces Round #663 (Div. 2) C

C.

Cyclic Permutations

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

A permutation of length nn is an array consisting of nn distinct integers from 11 to nn in arbitrary order. For example, [2,3,1,5,4][2,3,1,5,4] is a permutation, but [1,2,2][1,2,2] is not a permutation (22 appears twice in the array) and [1,3,4][1,3,4] is also not a permutation (n=3n=3 but there is 44 in the array).

Consider a permutation pp of length nn, we build a graph of size nn using it as follows:

  • For every 1≤i≤n1≤i≤n, find the largest jj such that 1≤j<i1≤j<i and pj>pipj>pi, and add an undirected edge between node ii and node jj
  • For every 1≤i≤n1≤i≤n, find the smallest jj such that i<j≤ni<j≤n and pj>pipj>pi, and add an undirected edge between node ii and node jj

In cases where no such jj exists, we make no edges. Also, note that we make edges between the corresponding indices, not the values at those indices.

For clarity, consider as an example n=4n=4, and p=[3,1,4,2]p=[3,1,4,2]; here, the edges of the graph are (1,3),(2,1),(2,3),(4,3)(1,3),(2,1),(2,3),(4,3).

A permutation pp is cyclic if the graph built using pp has at least one simple cycle.

Given nn, find the number of cyclic permutations of length nn. Since the number may be very large, output it modulo 109+7109+7.

Please refer to the Notes section for the formal definition of a simple cycle

Input

The first and only line contains a single integer nn (3≤n≤1063≤n≤106).

Output

Output a single integer 0≤x<109+70≤x<109+7, the number of cyclic permutations of length nn modulo 109+7109+7.

补题过程:比赛的时候这道题只看懂了题意却没有什么思路,之后看AC了的大佬博客的时候,才发现这也是一个找规律的题目。这道题有两种做法

第一是对于一个数组中的数字a,a的两侧均有大于a的元素,那么就会成环。通过找给的例子可以发现如果元素递增至n之后,再递减,便不成环,因此不成环的情况为:对于除了n以外的所有元素,均可选择放入n前面或n后面,从而有2^(n-1)种方式,于是结果可以表示为n!-2^(n-1)。

第二:因为这个输入的是一个数,输出的也是一个数,而且题目可以看出一些规律,所以可以暴力猜测公式(看到一个大佬直接两分钟猜测的公式就直接过了)

注意:因为数据可能很大,所以不能直接用公式,先把数据缩小一下然后使用。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
int main()
{
	int n;
	cin>>n;
	long long ans=1,sum=1;
	for(int i=n;i>0;i--) 
	{
		ans=(ans*i)%mod;
	}
	for(int i=1;i<=n-1;i++) 
	{
		sum=(sum*2)%mod;
	}
	ans=(ans-sum+mod)%mod; 
	cout<<ans<<endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值