打卡信奥刷题(3615)用C++实现信奥题 P11767 「KFCOI Round #1」缥缈

P11767 「KFCOI Round #1」缥缈

题目背景

这个世界这么大,是机缘让我们相遇,也是机缘促使我们分开。

是爱情促使我们沉沦,也是爱情让我们形同陌路。

在这一路上,为什么就刚好喜欢上你呢?

题目描述

你需要求出满足如下条件的长度为 mmm 的序列 BBB 的个数:

  • BBB 中全为正整数。
  • BBB 中不包含 xxx。
  • BBB 中元素两两不同。
  • BBB 中元素在范围 [1,n][1,n][1,n] 中。
  • BBB 中任意两个元素相差不会超过 ttt。

qqq 次询问,每次给出 xxx 和 ttt。

由于结果可能很大,输出答案对 109+710^9+7109+7 取余的结果。

输入格式

本题输入均为正整数。

第一行三个数 n,m,qn,m,qn,m,q。

接下来 qqq 行,每行两个数 x,tx,tx,t 代表一个询问。

输出格式

输出 qqq 行,每行一个数,第 iii 行代表第 iii 次询问的答案对 109+710^9+7109+7 取余的结果。

输入输出样例 #1

输入 #1

6 3 3
1 3
2 3
3 5

输出 #1

42
30
60

输入输出样例 #2

输入 #2

10 7 5
3 9
8 6
5 7
9 6
10 7

输出 #2

181440
5040
15120
10080
75600

说明/提示

数据范围

本题采用捆绑测试。

  • Subtask 1(10 points):n≤12n \le 12n≤12,m≤7m\le 7m≤7,q≤10q\le 10q≤10。
  • Subtask 2(15 points):n≤2000n \le 2000n≤2000,m=2m=2m=2,q≤2000q\le 2000q≤2000。
  • Subtask 3(15 points):m=2m=2m=2。
  • Subtask 4(20 points):x≤tx\le tx≤t。
  • Subtask 5(40 points):无特殊限制。

对于所有测试数据,2≤n≤2×1052\le n \le 2 \times 10 ^52≤n≤2×105,2≤m≤n2 \le m \le n2≤m≤n,1≤x≤n1 \le x \le n1≤x≤n,m−1≤t<nm - 1\le t < nm−1≤t<n,1≤q≤2×1051 \le q \le 2\times 10^51≤q≤2×105。

C++实现

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll mod = 1e9 + 7;
const ll M = 2e5 + 10;
ll fac[M], inv[M];
ll qpow(ll a, ll b) {
	ll res = 1;
	while (b) {
		if (b & 1ll) res = res * a % mod;
		a = a * a % mod; b >>= 1;
	}
	return res % mod;
}
ll C(ll n, ll m) {
	return fac[n] % mod * inv[m] % mod * inv[n - m] % mod;
}

int main() {
	fac[0] = 1;
	inv[0] = 1;
	for (ll i = 1; i <= 200000; i ++) {
		fac[i] = fac[i - 1] * i % mod;
		inv[i] = qpow(fac[i], mod - 2);
	}
    ll n, m, q;
    cin >> n >> m >> q;
    while (q--) {
        ll x, t, ans = 0;
        cin >> x >> t;
        ll all = n - t, have_x_cnt = 0;
        have_x_cnt = (min(n, x + t) - t) - (max(1ll, x - t)) + 1;
        ans += have_x_cnt % mod * C(t, m) % mod; ans %= mod;
        ans += (all - have_x_cnt) % mod * C(t + 1, m) % mod;
        ans %= mod;

        all = (n - t) - 2 + 1, have_x_cnt = 0;
        have_x_cnt = (min(n - 1, x + t - 1) - (t - 1)) - max(2ll, x - (t - 1)) + 1;
        if (t - 1 >= m) ans = (ans + mod - have_x_cnt * C(t - 1, m)) % mod;
        ans = (ans + mod) % mod;
        ans = (ans + mod - (all - have_x_cnt) * C(t, m)) % mod;
        ans = (ans + mod) % mod;
        ans = ans % mod * fac[m] % mod;
        cout << ans << "\n";
    }
    return 0;
}

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值