题意:给你四个正整数\(A,B,C,D\),且\(A\le B\le C \le D\),有\(A\le x\le B\le y\le C \le z\le D\),求最多有多少组\((x,y,z)\)能构成三角形.
题解:这题数据范围最大是\(5*10^5\),所以我们肯定不能枚举\(x,y\),但是由于题目限定我们知道:
x+z>y |||||| y+z>x
? 所以以上两种情况恒成立,我们只要看\(x+y>z\)的情况,我们可以枚举\(x+y\).
设\(x+y=m\),先求出\((x,y)\)有多少种组合,然后再计算\(z\)的情况,即\([C,m-1]\)的个数,二者相乘即可.
因为:\(B\le y \le C\) || \(y=m-x\), 所以得出:\(m-c\le x \le m-B\) || \(A\le x \le B\).
然后对\(x\)的区间取交集,取完后的区间长度就是\((x,y)\)的组合数.
最后要注意空集的情况即可.
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
using namespace std;
typedef pair<int,int> PII;
typedef pair<long,long> PLL;
ll a,b,c,d;
ll ans;
int main() {
ios::sync_with_stdio(false);cin.tie(0);
cin>>a>>b>>c>>d;
for(ll i=a+b;i<=b+c;++i){
ll res1=min(i-b,b)-max(i-c,a)+1;
ll res2=min(d,i-1)-c+1;
if(res1<0 || res2<0) continue;
ans+=res1*res2;
}
printf("%lld\n",ans);
return 0;
}
Codeforces Round #643 (Div. 2) C. Count Triangles (数学公式)
原文:https://www.cnblogs.com/lr599909928/p/12905738.html