返回顶部

Codeforces Round #643 (Div. 2) C. Count Triangles (数学公式)

  • 题意:给你四个正整数\(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;
    }
    
posted @ 2020-05-17 16:41  _Kolibri  阅读(193)  评论(0)    收藏  举报