思路:
白书上的做法比较难想到。
自己的做法是枚举第二长的边,这样就不会重复计算三角形。
但过程更加繁琐,考验自己数学功底多一点。
思路如下:
ll res = 0;
for(int i = 1; i <= n; i++){
ll cur = min(n - i + 1, i - 1);
res += cur * (cur - 1) / 2;
if(i - 1 > cur)
res += (i - 1 - cur) * (n - i);
}
要想通过就必须O(1)得解,对上述过程进行数学演算可以得出公式。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
const int MAXN = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1.0);
ll n, m, k;
ll pow_sum(ll x){
return x * (x + 1) * (2 * x + 1) / 6;
}
ll sim_sum(ll x){
return x * (x + 1) / 2;
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
while(cin >> n && n >= 3){
ll res = 0;
ll mid = (n + 2) >> 1;
res -= (n - mid) * (n * n + 2 * n);
res -= 2 * (pow_sum(n) - pow_sum(mid));
res += (3 * n + 2) * (sim_sum(n) - sim_sum(mid));
res += pow_sum(mid - 1) - sim_sum(mid - 1);
if(!(n & 1))
res -= (mid - 1) * (mid - 2) / 2;
cout << res << endl;
}
cerr << "execute time : " << (double)clock() / CLOCKS_PER_SEC << endl;
return 0;
}
未来可期。