有人說這套題C比D和E 從過題的人數上來看確實這樣 D題很好想 過的人很多 E題大佬說是三分裸題(大佬總能一眼看出)等下就補E
我們來講講C題 其實有個很簡單的而且細節也很少的方法 當時想了想 被隊友叫去搞D了
主要就是利用前綴和思想(雖然我求的是後綴)
我們知道 在 X<=Y<=Z的情況下 要構成三角形就只有一個限制 那就是 X+Y>Z
我們肯定要從a,b,c,d這幾個範圍下手
先枚舉最小的那條邊
a<=X<=b 從a到b枚舉一遍
對於第2條邊 我們通過它界定一個範圍 我們知道第二條邊的最大值是 b 最小值是c
那麼 我們得到一個初步的範圍 X+b-1,X+c-1
這是第三條邊的一個可行邊界範圍(我亂說的 不知道怎麼說)
大概意思是 對於 X和c 這兩條邊來說 最大的可行邊就是 X+c-1
對於 X和c-1 這兩條邊來說 最大的可行邊就是 X+c-2
...以此類推 對於 X和b 這兩條邊來說 最大的可行邊就是 X+b-1
那麼我們進行後綴和的修改
對於 後綴和數組q
q[x+b-2]--,q[x+c-1]++;
X+b-2 X+b-1 X+b X+b+1...... X+c-2 X+c-1
-1 0 0 0 0 1
這樣 我們做一遍後綴和
X+b-2 X+b-1 X+b X+b+1...... X+c-2 X+c-1
0 1 1 1 1 1
但是這僅僅是把每一種組合的邊界標記出來 並沒有得到完整的可行邊(比如比邊界邊小一些的)
我們考慮一下 對於 邊界是 X+c-1 的組合 是不是所有 c<=k<=X+c-1 的邊都是可行解
也就是說任何小於邊界邊的邊都是可以計入答案的
那麼對於上面的後綴和 只標記出了邊界邊 我們再做一次後綴和 就可以完美的標記出每條邊作爲最大邊對答案的貢獻了
X+b-2 X+b-1 X+b X+b+1...... X+c-2 X+c-1
c-b+1 c-b+1 c-b c-b-1 2 1
最後我們只要計算區間 c~d之間的和就行啦
爲了方便 我把數組開大了一倍
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
typedef long long ll;
ll q[N];
int main(){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
for(int i = a; i <= b; i++){
int l = i+b-1;
int r = i+c-1;
q[l-1]--;
q[r]++;
}
for(int i = N-2; i >= 1; i--) q[i]+=q[i+1];
for(int i = N-2; i >= 1; i--) q[i]+=q[i+1];
ll ans = 0;
for(int i = c; i <= d; i++) ans+=q[i];
printf("%lld\n",ans);
return 0;
}