C. Count Triangles(差分记录两个区间中的数相加得到的每个数可以由几种方式得到)

Problem - C - Codeforces

C. Count Triangles(差分记录两个区间中的数相加得到的每个数可以由几种方式得到)_第1张图片

像所有不知名的数学家一样,尤里也有自己最喜欢的数字:A、B、C和D,其中A S B

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

请注意在第一个例子中,Yuri可以用边(1,3,3),(2,2,3),(2,3,3)和(2,3,4)组成三角形。在第二个例子中,Yuri可以用边(1,2,2)、边(2,2,2)和边(2,2,3)组成三角形。在第三个例子中,Yuri只能组成一个边长为5 - 105的等边三角形。

题解:
万万没想到差分还能这样用

正如题目所说:
差分记录两个区间中的数相加得到的每个数可以由几种方式得到(十分新奇的差分使用方式(对我而言))

x + y最小值是a + b,最大值是b + c

正如上面所说差分,我们得到一些数(x + y)并且知道这每个数可以有多少种方式构成

再记录一下前缀和,通过s[N] - s[i]

我们可以知道x + y大于i的有多少种,相加即可

 

#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
typedef pair PII;
#define int long long
int s[1000050];
void solve()
{
	int a,b,c,d;
	cin >> a >> b >> c >> d;
	for(int i = a;i <= b;i++)
	{
		s[i + b] ++;
		s[i + c + 1] --; 
	}
	for(int i = 1;i <= 1000000;i++)
	{
		s[i] = s[i - 1] + s[i];
	}
	for(int i = 1;i <= 1000000;i++)
	{
		s[i] = s[i - 1] + s[i];
	}
	int ans = 0;
	for(int i = c;i <= d;i++)
	{
		ans += (s[1000000] - s[i]);
	}	
	cout << ans;
}


signed main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	int t = 1;
//	cin >> t;
	while(t--)
	{
		solve(); 
	}
}

你可能感兴趣的:(算法,c++,数据结构)