G - Great dinner Gym - 102700G 排队时两人有次序的问题

探讨了在特定约束条件下,如何计算学生排列方式的数量。该算法问题来源于VJudge平台,涉及数学组合、动态规划及高效算法实现。文章分析了问题背景,提供了代码示例,并解释了关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://vjudge.net/contest/392956#problem/G
G - Great dinner Gym - 102700G
UNAL is about to restart classes and the leaders of the algorithms group want to receive all its members with a great dinner in the university campus central dining room.

The group has N members (excluding the leaders) numbered from 1 to N and the leaders want to organize them in a row before entering the dining room, in order to avoid any disorder. However, some students enjoy teasing others. In particular, there are M bullies and M victims, all of these 2×M students are different. Each bully annoys exactly one victim and each victim is being bullied by exactly one bully. To make dinner a great time for everyone, the leaders want to ensure that if student A annoys student B, B must not be ahead of A in the line.

Leaders enjoy math challenges, so they wonder how many ways can they organize all students on a line. Can you help them with that?

Input
The first line contains two integers N (1≤N≤105) and M (0≤2×M≤min(2×103,N)) separated by a space — The number of students, and the number of bullies and victims, respectively.

Each of the following M lines will contain two integers A and B (1≤A,B≤N) separated by a space, which means that student B must not be ahead of A in the line. It is guaranteed that each, A and B, appears at most once in the input.

Output
Output one integer, the number of ways the leaders can organize the students on a line modulo 109+7.

Examples
Input
4 2
2 1
4 3
Output
6
Input
4 1
1 3
Output
12
Note
For the first case, there are only 6 ways to organize the students:

1 2 3 4
1 3 2 4
1 3 4 2
3 1 2 4
3 1 4 2
3 4 1 2

题目意思:就是对n求阶乘得s,对然后求2^m得sum,然后s/sum,再对mod取余

思路:在求s的过程中对s取余,不然超ll,因为2^64次方就超ll,所以得在求s的过程中把sum逐渐除掉

上面是我复制过来的别人的博客;;借用一下这位大婶的博客
这道题的规律就是n个人排序所以要求n的阶乘,然后是我们有的两个人的次序已经安排好啦,所以应该除以两个人的先后次序也就是除以2,然后得到n的阶乘除以2的m次方的结果mod1e9一下,技巧上面已经有啦。
切记:::::
排序是阶乘,
二人有序列就除以一次2;;

#include <iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<math.h>
#define ll long long
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod=1e9+7;

//每一步中取余,和,总的取余对结果没有影响,
//因为2^64就超ll,所以不能把2^m单独拿出来,
//需要在求n的阶乘的时候就给它除掉,
//总的s/总的sum,和,在求s的过程中慢慢把sum给除掉结果一样
//哪怕中间有对s的取余
int main()
{
   ll n,m;
   cin>>n>>m;
   ll s=1;
   for(int i=1;i<=m;i++)
   {
       int q,w;
       cin>>q>>w;
   }
   for(ll i=1;i<=n;i++)
   {
       if(i%2==0&&m!=0)
       {
           s=s*(i/2);
           m--;
       }
       else s=s*i;
       s=s%mod;
   }
   cout<<s<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值