C. Count Triangles
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Like any unknown mathematician, Yuri has favourite numbers: AA, BB, CC, and DD, where A≤B≤C≤DA≤B≤C≤D. Yuri also likes triangles and once he thought: how many non-degenerate triangles with integer sides xx, yy, and zz exist, such that A≤x≤B≤y≤C≤z≤DA≤x≤B≤y≤C≤z≤D holds?
Yuri is preparing problems for a new contest now, so he is very busy. That's why he asked you to calculate the number of triangles with described property.
The triangle is called non-degenerate if and only if its vertices are not collinear.
Input
The first line contains four integers: AA, BB, CC and DD (1≤A≤B≤C≤D≤5⋅1051≤A≤B≤C≤D≤5⋅105) — Yuri's favourite numbers.
Output
Print the number of non-degenerate triangles with integer sides xx, yy, and zz such that the inequality A≤x≤B≤y≤C≤z≤DA≤x≤B≤y≤C≤z≤D holds.
Examples
input
Copy
1 2 3 4
output
Copy
4
input
Copy
1 2 2 5
output
Copy
3
input
Copy
500000 500000 500000 500000
output
Copy
1
Note
In the first example Yuri can make up triangles with sides (1,3,3)(1,3,3), (2,2,3)(2,2,3), (2,3,3)(2,3,3) and (2,3,4)(2,3,4).
In the second example Yuri can make up triangles with sides (1,2,2)(1,2,2), (2,2,2)(2,2,2) and (2,2,3)(2,2,3).
In the third example Yuri can make up only one equilateral triangle with sides equal to 5⋅1055⋅105.
=========================================================================
考虑最为暴力的方法,也就是统计x+y>z的数量, 枚举z,对于每一个z,暴力枚举大于z的x+y,显然会超时。值得注意的是z1<z2 <x+y 即z<x+y这一属性是满足后缀和的,也就是我们统计出来全部等于 z`的x+y数目,做一个后缀和,要求大于z1的,只需要提取后缀和数组sum[z1+1]即可。
那么现在问题就变成了枚举x+y, 我们考虑固定x,那么y的枚举范围显然是b--c,这一枚举可以用差分快速解决,这样对差分数组做一次前缀和,再对前缀和数组做一次后缀和,就完美的实现了枚举操作,并不需要过多数学知识。
# include<bits/stdc++.h>
using namespace std;
# define mod 1000000007
typedef long long int ll;
ll sum[1000000+10];
int main ()
{
ll a,b,c,d;
cin>>a>>b>>c>>d;
for(int i=a;i<=b;i++)
{
sum[i+b]++;
sum[i+c+1]--;
}
for(int i=1;i<=1000000+5;i++)
{
sum[i]=sum[i-1]+sum[i];
}
ll ans=0;
for(int i=1000000;i>=0;i--)
{
if(i>=c&&i<=d)
{
ans+=sum[i+1];
}
sum[i]+=sum[i+1];
}
cout<<ans;
return 0;
}