300
這題讓計算三條邊分別不超過
正確的做法是利用容斥原理
總結一下,當計算某些值比較困難(合法情況),但是反過來比較簡單的時候(總數和非法情況),就可以考慮容斥。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1000000007;
// *inv%mod 相當於/6
const ll inv = 166666668;
const ll LARGE = 3e18;
ll calc(ll n){
ll res = n*(n+1);
res %= mod;
res *= (2*n+1);
res %= mod;
res *= inv;
res %= mod;
return res;
}
ll solve(ll a,ll b,ll c){
ll res = 0;
ll MIN = min(a,b);
ll MAX = max(a,b);
ll tmp = 0;
// part 1
if(c>1){
ll end = min(MIN,c-1);
tmp += end*(1+end)/2;
tmp %= mod;
tmp *= c;
tmp -= calc(end);
tmp %= mod;
tmp += mod;
tmp %= mod;
res += tmp;
//cout<<"part 1 = "<<tmp<<endl;
}
// part 1 end
// part 2
tmp = 0;
ll l = MIN+2;
ll r = min(c,MAX+1);
ll cnt = r-l+1;
if(cnt>0){
tmp += ((c-l+1)+(c-r+1))*cnt/2;
tmp %= mod;
tmp *= MIN;
tmp %= mod;
res += tmp;
//cout<<"part 2 = "<<tmp<<endl;
}
// part 2 end
// part 3
if(c>MAX+1){
tmp = 0;
ll cnt = min(MIN,c-MAX)-1;
tmp += (MIN-1+(MIN-cnt))*cnt/2;
tmp %= mod;
tmp *= (c-MAX);
tmp %= mod;
tmp += calc(cnt);
tmp %= mod;
tmp -= MIN*((1+cnt)*cnt/2%mod);
tmp %= mod;
if(tmp<0){
tmp += mod;
}
res += tmp;
//cout<<"part 3 = "<<tmp<<endl;
}
// part 3 end
res %= mod;
return res;
}
class TriangleTriples{
public:
int count(ll A, ll B, ll C){
ll res = A*B;
res %= mod;
res *= C;
res -= (solve(A,B,C) + solve(C,A,B) + solve(B,C,A))%mod;
res %= mod;
res += mod;
res %= mod;
return res;
}
};