题意:
给定四边形的四条边,每条边si∈[s1,s2],求能形成的四边形总数
数据范围:
t=1e3,三条边1-1e5,剩下一条1-1e3
链接:
https://nanti.jisuanke.com/t/41304
题解:
设四条边a,b,c,d,枚举d,容斥将边范围化为[1,a1-1],[1,a2]
于是只需考虑范围为[1,Ra]的情况,考虑容斥,总数为RaRbRc,减去每条边分别为最长边&&构不成四边形的情况,因为边长不为0,所以不构成四边形时不会存在两条最长边。
若a为最长边,只需要统计b+c+d≤a,即b+c≤a-d,即[1,Rb]+[1,Rc]≤[1-d,Ra-d],若d为最长边,只需要统计a+b+c≤d,即a+b≤d-c,即[1,Ra]+[1,Rb]≤[d-Rc,d-Rd]
以上两张情况都可以转化为[1,Ra]+[1,Rb]≤[1,Rc]的问题,或其之差
这个问题我们可以画一张表格记数,然后高斯求和即可,细节细节细节!!!
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll cal1(ll n){
return n*(n+1)*((n<<1)+1)/6;
}
ll cal2(ll f,ll e,ll l){
return ((e-f+1)*(e+f)/2)*l;
}
ll cal3(ll f,ll e,ll l){
if(f>e)return 0;
return (e-f+1)*l*f+(l-f)*((e-f)*(e-f+1)/2)-cal1(e-f);
}
ll cal4(ll a,ll b,ll c){
if(a>b)swap(a,b);
ll ret=0,cnt=0;
if(c<=a)return cal1(c);
else{
ret+=cal1(a);
if(c<=b){
return ret+cal2(a+1,c,a);
}
else{
ret+=cal2(a+1,b,a);
if(c<=a+b-1){
return ret+cal3(b+1,c,a-1);
}
else{
ret+=cal3(b+1,a+b-1,a-1);
return ret;
}
}
}
}
ll cal5(ll a,ll b,ll c){
if(a>b)swap(a,b);
ll ret=0;
if(c<=a)return c*(c+1)/2;
else{
ret+=a*(a+1)/2;
if(c<=b){
return ret+(c-a)*a;
}
else{
ret+=(b-a-1)*a;
if(c<=a+b-1){
return ret+(a+a-(c-b))*(c-b+1)/2;
}
else{
ret+=a*(a+1)/2;
return ret;
}
}
}
}
ll cal6(ll a,ll b,ll c){
return cal5(a,b,c)*c-cal4(a,b,c);
}
ll cal7(ll a,ll b,ll c,ll d){
ll ret=a*b*c;
ret-=cal6(a,b,c-d);
ret-=cal6(a,c,b-d);
ret-=cal6(b,c,a-d);
ret-=(cal6(a,b,d-1)-cal6(a,b,d-c-1));
return ret;
}
ll cal8(ll a1,ll a2,ll b1,ll b2,ll c1,ll c2,ll d){
a1--,b1--,c1--;
return cal7(a2,b2,c2,d)
-cal7(a1,b2,c2,d)
-cal7(a2,b1,c2,d)
-cal7(a2,b2,c1,d)
+cal7(a2,b1,c1,d)
+cal7(a1,b2,c1,d)
+cal7(a1,b1,c2,d)
-cal7(a1,b1,c1,d);
}
void check(){
cout<<cal1(2)<<" "<<cal1(3)<<" "<<cal1(4)<<endl;
cout<<cal2(1,3,1)<<" "<<cal2(2,4,2)<<endl;
cout<<cal3(5,7,6)<<" "<<cal3(2,4,5)<<endl;
cout<<endl;
for(int i=1;i<=15;i++){
cout<<i<<" "<<cal4(5,9,i)<<" "<<cal4(5,9,i)-cal4(5,9,i-1)<<endl;
cout<<i<<" "<<cal5(5,9,i)<<" "<<cal5(5,9,i)-cal5(5,9,i-1)<<endl;
}
cout<<endl;
cout<<cal7(1,1,1,1)<<" "<<cal7(2,2,2,2)<<" "<<cal7(3,4,2,3)<<" "<<cal7(3,4,2,1)<<endl;
cout<<endl;
}
int main(){
//check();
int t;cin>>t;
while(t--){
int q,w,e,r,t,y,u,i;cin>>q>>w>>e>>r>>t>>y>>u>>i;
ll ans=0;
for(int j=u;j<=i;j++){
ans+=cal8(q,w,e,r,t,y,j);
}
cout<<ans<<endl;
}
}