CF1946E 题解

Blog


赛场上差一点做出来。

首先发现左右两部分是比较独立的,所以可以分开计算后合并。

注意到我们可以把整个数集分成左右两部分,即 (n1pm11)

然后我们不妨只考虑左边。

发现左边的最大值也已经确定,且最大值右边的所有数可以随便选,即 (pi+12pi1)

由于内部需要换顺序,所以还要乘上 (pi+1pi1)!

右边同理。最后的答案即为全部的乘积。

/*******************************
| Author:  DE_aemmprty
| Problem: E. Girl Permutation
| Contest: Codeforces Round 936 (Div. 2)
| URL:     https://codeforces.com/contest/1946/problem/E
| When:    2024-03-22 22:37:51
| 
| Memory:  256 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;

long long read() {
    char c = getchar();
    long long x = 0, p = 1;
    while ((c < '0' || c > '9') && c != '-') c = getchar();
    if (c == '-') p = -1, c = getchar();
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * p;
}

const int N = 2e5 + 7;
const long long mod = 1e9 + 7;

int n, m1, m2;
int p[N], q[N];
long long fac[N];

long long ksm(long long x, long long y) {
    long long res = 1;
    for (; y; y >>= 1, (x *= x) %= mod)
        if (y & 1)
            (res *= x) %= mod;
    return res;
}

long long C(long long x, long long y) {
    if (x < y) return 0;
    return fac[x] * ksm(fac[y] * fac[x - y] % mod, mod - 2) % mod;
}

void solve() {
    n = read(), m1 = read(), m2 = read();
    for (int i = 1; i <= m1; i ++) p[i] = read();
    for (int i = 1; i <= m2; i ++) q[m2 - i + 1] = n - read() + 1;
    if (p[m1] + q[m2] != n + 1 || p[1] != 1 || q[1] != 1) {
        cout << 0 << '\n';
        return ;
    }
    long long res = 1ll;
    for (int i = 1; i < m1; i ++) {
        int siz = p[i + 1] - p[i] - 1;
        res = res * fac[siz] % mod * C(p[i + 1] - 2, p[i] - 1) % mod;
    }
    long long res2 = 1ll;
    for (int i = 1; i < m2; i ++) {
        int siz = q[i + 1] - q[i] - 1;
        res2 = res2 * fac[siz] % mod * C(q[i + 1] - 2, q[i] - 1) % mod;
    }
    cout << res * res2 % mod * C(n - 1, p[m1] - 1) % mod << '\n';
}

signed main() {
    int t = 1;
    t = read();
    fac[0] = 1;
    for (int i = 1; i <= 200000; i ++) fac[i] = fac[i - 1] * i % mod;
    while (t --) solve();
    return 0;
}

作者:DE_aemmprty

出处:https://www.cnblogs.com/aemmprty/p/18090768

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   DE_aemmprty  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示