T1
题目描述
小 S 在和小 W 玩游戏!
小 S 有一个 n 阶排列 p1,p2,⋯,pn。小 S 和小 W 轮流操作,小 S 先手。每次操作时,玩家可以以任意顺序重排 p1,p2,⋯,pp1。如果一个玩家操作时发现 p1 和自己之前某次操作时的 p1 相同,那么这名玩家就会输掉游戏。
小 S 和小 W 都足够聪明,所以小 W 一眼就看出小 S 的这个排列是先手必胜的!为了公平,小 W 提出在所有 n 阶排列中随机一个作为初始排列。听到这个提议,小 S 决定先计算自己的胜率。他需要你帮忙计算所有 n 阶排列中有多少个是后手必胜的。
答案对 10^9+7 取模。
输入格式
第一行一个正整数 n。
输出格式
一行一个非负整数,表示后手必胜的排列数对 10^9+7 取模后的结果。
思路
先手必胜当且仅当p1不是p1~p1的最小值。
反之,先手操作后原来的p1肯定在长度为新的p1的前缀内,这样后手就能把原来的p1再换回来,先手就输了。如果满足条件,先手可以把长度为p1的前缀内的最小值换到开头,同理后手就输了。
枚举p1,设p1=k,答案为:
((n-k)!/((n-k)-(k-1))!)*(n-k)!
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7,N=2e7+9;
int n;
int jc[N],inv[N];
int qp(int a,int b){
int ans=1;
while(b){
if