C. Count Triangles(组合数学)

C. Count Triangles(组合数学)

传送门

思路:考虑所有的 x + y x+y 组成的可行解。

显然 x , y , z x,y,z 组成三角形 x + y > z \rightarrow x+y>z , 因为 z m i n = c z_{min}=c ,所以 ( x + y ) m i n > c (x+y)_{min}>c .

又因为 x m i n = a , y m i n = b x_{min}=a,y_{min}=b .所以 x + y x+y 具有可行解的最小值为 m a x ( c + 1 , a + b ) max(c+1,a+b) .

最大值即 b + c b+c .

所以 x + y [ m a x ( c + 1 , a + b ) , b + c ] x+y\in[max(c+1,a+b),b+c]

接下来考虑每种 x + y x+y 对答案的贡献,首先考虑对于当前 i = x + y i=x+y , z z 的取值。

显然 z z 只能取 c , c + 1 i 2 , i 1 c,c+1\dots i-2,i-1 .又因为 c m a x = d c_{max}=d .所以

z z 可选的个数为 c n t z = m i n ( d , i 1 ) c + 1 = m i n ( d + 1 , i ) c cnt_z=min(d,i-1)-c+1=min(d+1,i)-c .

接下来考虑 x + y x+y 可选的个数.

y : [ b , , c ] x : [ a , , b ] y x [ i c , , i b ] . i a + b , i b + c i b a , i c c y [ m a x [ i c , a ] , m i n [ i b , b ] ] x + y : c n t x + y = m i n ( i b , b ) m a x ( i c , a ) + 1 y:[b,\dots,c]\\x:[a,\dots,b]\\对每个y,x的对应值为[i-c,\dots,i-b].\\因为i\geq a+b,i\leq b+c\Rightarrow i-b\geq a,i-c\leq c\\所以y的取值的范围为:[max[i-c,a],min[i-b,b]]\\即x+y可选的个数为:cnt_{x+y}=min(i-b,b)-max(i-c,a)+1个。
根据乘法原理可得当前 x + y x+y 的贡献为:
c n t x + y × c n t z cnt_{x+y}\times cnt_z
综上可以通过遍历 x + y x+y 得到答案。

时间复杂度: O ( m a x ( b , c a + 1 ) ) O(max(b,c-a+1))

AC代码:

#include<iostream>
#include<algorithm>
typedef long long ll; 
using namespace std;
signed main(){
	ll a,b,c,d;
	cin>>a>>b>>c>>d;
	ll ans=0;
	for(ll 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;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106170287
今日推荐