题目:https://codeforces.com/contest/1550/problem/D
Let’s call an integer array a1,a2,…,an good if ai≠i for each i.
Let F(a) be the number of pairs (i,j) (1≤i<j≤n) such that ai+aj=i+j.
Let’s say that an array a1,a2,…,an is excellent if:
a is good;
l≤ai≤r for each i;
F(a) is the maximum possible among all good arrays of size n.
Given n, l and r, calculate the number of excellent arrays modulo 109+7.
Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.
The first and only line of each test case contains three integers n, l, and r (2≤n≤2⋅105; −109≤l≤1; n≤r≤109).
It’s guaranteed that the sum of n doesn’t exceed 2⋅105.
Output
For each test case, print the number of excellent arrays modulo 109+7.
Example
input
4
3 0 3
4 -3 5
42 -33 55
69 -42 146
output
4
10
143922563
698570404
Note
In the first test case, it can be proven that the maximum F(a) among all good arrays a is equal to 2. The excellent arrays are:
[2,1,2];
[0,3,2];
[2,3,2];
[3,0,1].
写个题解以后再回头看看,怎么证明的。
题目读懂了,,怎么做还是不会,看了题解证明发现真的难,没看懂为什么证明,题解代码却不难。。如果有大佬看得懂下面的证明可以评论哦,谢谢啦
题解证明:
代码:
#include <iostream>
using namespace std;
const int mod = int(1e9) + 7;
int norm(int a){
while(a >= mod)
a -= mod;
while(a < 0)
a += mod;
return a;
}
int mul(int a,int b){ //求乘积 函数
return int(a * 1ll * b % mod);
}
int binPow(int a,int k){ //求逆元函数
int ans = 1;
while(k > 0){
if(k&1)
ans = mul(ans,a);
a = mul(a,a);
k >>= 1;
}
return ans;
}
const int N = 200*1000 + 55;
int f[N],inf[N]; //阶乘,阶乘的逆元
void precalc(){
f[0] = inf[0] = 1; //0的阶乘和阶乘逆元
for(int i = 1;i<N;i++){ //费马小定理
f[i] = mul(f[i-1],i);
inf[i] = binPow(f[i],mod-2);
}
}
int C(int n,int k){ //组合数
if(k < 0 || n < k)
return 0;
return mul(f[n],mul(inf[n-k],inf[k])); //C(n,m) = n!/((n-m)!*m!) % (1e9+7)
}
int n,l,r;
inline void solve(){
int half = n / 2;
int st = min(1-l, r-n);
int ans = mul(st,C(n,half));
if(n & 1)
ans = norm(ans+mul(st,C(n,half + 1)));
for(int k = st+1; ;k++){
int lf = max(1, l + k);
int rg = min(n, r - k);
if(rg + 1 - lf < 0)
break;
ans = norm(ans + C(rg + 1 - lf, half - (lf - 1)));
if(n & 1)
ans = norm(ans + C(rg + 1 - lf, half + 1 - (lf - 1)));
}
cout << ans << endl;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
precalc();
int t; cin >> t;
while(t--){
cin >> n >> l >> r;
solve();
}
return 0;
}