C. Count Triangles -差分 -枚举

Problem - C - Codeforces

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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinsanma and Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值