daimayuan每日一题#851 Good Permutations

Good Permutations - 题目 - Daimayuan Online Judgehttp://oj.daimayuan.top/course/11/problem/851思路:纯纯推公式题。

首先考虑如何成环,

对于数列中三个数 ....a1......a2.....a3.......,如果a1,a3是对于a2满足条件的两个数,namo,a2连a1,a2连a3.因为是个排列,所以a1,a3肯定有个是大的数,假设a1>a3,namo,由条件可以得到,a1到a3之间没有比a2大的数,namo,a1和a3肯定也可以连一条边。这时候就可以就可以构成环。

namo,怎么求呢,不如考虑其的反面,有多少个不难构成这种情况,不难发现就是要构成这种情况:

 

最高点那个位置就是n,namo还剩下n-1个数,考虑n左边有0,1,2......n-1个数的情况之和。就是

\sum C(i,n-1),二项式之和就是2^{n-1}

所以就推出了公式: n!-2^{n-1}

代码相当简单:

//#define pei_pei_

//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstring>
#include<functional>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<algorithm>
#include<set>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define FI first
#define SE second
#define _for(type,i,a,b) for(type i=(a);i<(b);++i)
#define _efor(type,i,a,b) for(type i=(a);i<=(b);++i)
#define _rfor(type,i,a,b) for(type i=(a);i>(b);--i)
#define _refor(type,i,a,b) for(type i=(a);i>=(b);--i)
#define _sfor(p,st) for(auto &p:st)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,int> pdi;
const double pi=acos(-1.0);
const double eps=1e-8;
const int mod=1e9+7;
const int _mod=998244353;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int maxn=200010;
ull base=1331;
//-------------------------------------------------------------------


    ll po[1000010];

    ll f_mod(ll x,ll n){
        ll res=1;
        while(n){
            if(n&1)res=res*x%mod;
            x=x*x%mod;
            n>>=1;
        }
        return res;
    }
//-------------------------------------------------------------------
signed main(){
    //ifstream cin("D:\\in.txt");
    //ofstream cout("D:\\out.txt");
    IOS;
    #ifdef pei_pei_
    double be=clock();
    #endif // err

//==================================================================
   po[0]=1;
   _efor(int,i,1,1000000){
        po[i]=(po[i-1]*i)%mod;;
   }


   ll T,n;
   cin>>T;
   while(T--){
        cin>>n;
        cout<<(po[n]-f_mod(2,n-1)+mod)%mod<<'\n';
   }



//==================================================================

    #ifdef pei_pei_
    double en=clock();
    cout<<endl<<"time: "<<fixed<<setprecision(8)<<en-be<<" ms";
    #endif // err
    return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值