题目 | 序列统计
LibreOJ10235. 序列统计
题目描述
给定三个正整数
输入格式
输入第一行包含一个整数
第二到第
输出格式
输出包含
样例
输入
2
1 4 5
2 4 5
输出
2
5
对于第一组输入,满足条件的两个序列为
数据范围与提示
对于全部输入,
题解
长度为
我们先从长度为
单调不减不好处理,我们令
原序列与变换后的序列能够保证一一对应,并且若变换后的序列满足单调增,原序列一定单调不减。
借助新序列,我们容易得出这种情况的数量为:
长度为
我们将上面的结论推广,计算长度为
我们令
这种情况的数量为:
长度为
最后我们需要将所有情况加到一起,即:
直接求和肯定要超时,尝试进行变形:
最后结果仅为一个组合数。数据规模
代码
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e6 + 3;
long long fact[MOD + 10];
void init()
{
fact[0] = 1;
for (int i = 1; i <= MOD; i++)
fact[i] = fact[i - 1] * i % MOD;
}
long long fast_pow(long long a, long long b, long long p)
{
b %= p;
long long ans = 1;
while (b)
{
if (b % 2)
ans = a * ans % p;
a = a * a % p;
b /= 2;
}
return ans;
}
inline long long inv(long long x, long long p)
{
return fast_pow(x, p - 2, p);
}
long long comb(long long a, long long b, long long p)
{
if (b > a)
return 0;
if (a < p && b < p)
return fact[a] * inv(fact[b], p) % p * inv(fact[a - b], p) % p;
return comb(a % p, b % p, p) * comb(a / p, b / p, p) % p;
}
int main()
{
int n;
cin >> n;
init();
while (n--)
{
long long N, L, R;
cin >> N >> L >> R;
cout << ((comb(N + (R - L + 1), R - L + 1, MOD) - 1) % MOD + MOD) % MOD << endl;
}
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi