Codeforces Round #643 (Div. 2) C. Count Triangles

C. Count Triangles

题目链接-C. Count Triangles
在这里插入图片描述
在这里插入图片描述
题目大意
给你四个数ABCDA,B,C,D,求有多少个三边为xyzAxByCzDx,y,z (A ≤ x ≤ B ≤ y ≤ C ≤ z ≤ D)的三角形

解题思路
组合数学

  • 若枚举x,y,zx,y,z的值肯定是会超时的,所以我们可以枚举满足条件的x+yx+y的值
  • 若想能x,y,zx,y,z组成三角形,那么需要x+y>zx+y>z, 又z[C,D]z∈[C,D],所以(x+y)min>C(x+y)_{min}>C
  • 因为x[A,B]x∈[A,B]y[B,C]y∈[B,C],又(x+y)min>C(x+y)_{min}>C,所以(x+y)min=max(A+B,C+1)(x+y)_{min}=max(A+B,C+1),易得x+y[max(A+B,C+1),B+C]x+y∈[max(A+B,C+1),B+C]
  • 然后for循环枚举可行的x+yx+y值,对于每个ii,满足条件的zz值范围为[C,i1][C,i-1],又因为zmax=Dz_{max}=D,所以可取zz的个数为min(D,i-1)-C+1,即min(D+1,i)-C
  • 因为x+y=ix+y=i,确定了其中一个数的值,另一个数的也就确定了,所以我们可以求出对于每个ii,可取xx值的个数,即是满足x+y==ix,yx,y对数
  • 容易看出xx的变化范围为[iC,iB][i-C,i-B],不过xx还需要在[A,B][A,B]之内,取相交区间就行了,所以x[max(iC,A),min(iB,B)]x∈[max(i−C,A),min(i−B,B)],所以满足x+y=ix+y=ix,yx,y对数就为min(iB,B)max(iC,A)+1min(i-B,B)-max(i-C,A)+1
  • 根据乘法原理,可以可得对于当前ii满足条件的x,y,zx,y,z组数为min(D+1,i)-C*min(i-B,B)-max(i-C,A)+1,即可得到答案

附上代码

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=2e5+10;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
inline void read(int &x){
    char t=getchar();
    while(!isdigit(t)) t=getchar();
    for(x=t^48,t=getchar();isdigit(t);t=getchar()) x=x*10+(t^48);
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	int a,b,c,d,ans=0;
	cin>>a>>b>>c>>d;
	for(int i=max(c+1,a+b);i<=b+c;i++)
		ans+=(min(d+1,i)-c)*(min(i-b,b)-max(i-c,a)+1);
	cout<<ans<<endl;
	return 0;
}
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试
应支付0元
点击重新获取
扫码支付

支付成功即可阅读