Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- using ld = long double;
- using pii = pair<int, int>;
- #define f first
- #define s second
- #define F0R(i, n) for(int i = 0; i < n; ++i)
- #define FOR(i, a, b) for(int i = a; i < b; ++i)
- const int MOD = 1e9 + 7;
- const ld eps = 1e-4;
- const int mxN = 41;
- int mul(int x, int y){
- return (1LL*x*y)%MOD;
- }
- int add(int x, int y){
- x += y; if(x >= MOD) x -= MOD;
- return x;
- }
- int binpow(int x, int y){
- int z = 1;
- while(y > 0){
- if(y%2==1){
- z = mul(z, x);
- }
- x = mul(x, x);
- y /= 2;
- }
- return z;
- }
- int inv(int x){
- return binpow(x, MOD-2);
- }
- ld sq(int x){
- return x*x;
- }
- ld dist(pii A, pii B){
- return sqrt(sq(B.f-A.f)+sq(B.s-A.s));
- }
- struct tri{
- pii a, b, c; int ia, ib, ic;
- ld area;
- tri(pii A, pii B, pii C, int IA = -1, int IB = -1, int IC = -1) : a(A), b(B), c(C), ia(IA), ib(IB), ic(IC) {
- ld ab = dist(a, b), bc = dist(b, c), ca = dist(c, a);
- ld semi = (ab+bc+ca)/2;
- area = sqrt(semi*(semi-ab)*(semi-bc)*(semi-ca));
- }
- bool operator < (tri other){
- return area < other.area;
- }
- };
- bool inside(tri a, pii b){
- tri A(a.a, a.b, b);
- tri B(a.a, a.c, b);
- tri C(a.b, a.c, b);
- ld tot = A.area+B.area+C.area;
- return abs(a.area-tot) <= eps;
- }
- int fac[mxN];
- int ifac[mxN];
- int choose(int n, int k){
- return mul(mul(fac[n], ifac[k]), ifac[n-k]);
- }
- int n;
- vector<pii> v;
- vector<tri> t;
- int amt[mxN][mxN][mxN];
- int ind[mxN][mxN][mxN];
- vector<int> dp;
- int main(){
- ios_base::sync_with_stdio(0); cin.tie(0);
- cout << fixed << setprecision(4);
- fac[0] = 1;
- FOR(i, 1, mxN) fac[i] = mul(fac[i-1], i);
- ifac[mxN-1] = inv(fac[mxN-1]);
- for(int i = mxN - 2; i >= 0; i--) {
- ifac[i] = mul((i+1),ifac[i+1]);
- //cout << ifac[i] << ' ' ;
- }
- //cout << endl;
- cin >> n;
- v.resize(n);
- F0R(i, n){
- cin >> v[i].f >> v[i].s;
- }
- F0R(i, n){
- F0R(j, i){
- F0R(k, j){
- tri T(v[i], v[j], v[k], i, j, k);
- t.push_back(T);
- int tot = 0;
- F0R(l, n){
- if(l==i||l==j||l==k) continue;
- if(inside(T, v[l])){
- tot++;
- }
- }
- amt[i][j][k] = amt[i][k][j] = amt[j][i][k] = amt[j][k][i] = amt[k][i][j] = amt[k][j][i] = tot;
- }
- }
- }
- sort(t.begin(), t.end());
- dp.resize(t.size());
- F0R(i, (int)t.size()){
- ind[t[i].ia][t[i].ib][t[i].ic] = i;
- ind[t[i].ib][t[i].ia][t[i].ic] = i;
- ind[t[i].ia][t[i].ic][t[i].ib] = i;
- ind[t[i].ib][t[i].ic][t[i].ia] = i;
- ind[t[i].ic][t[i].ib][t[i].ia] = i;
- ind[t[i].ic][t[i].ia][t[i].ib] = i;
- }
- if(amt[t.back().ia][t.back().ib][t.back().ic] != n-3) {
- cout << "0\n";
- return 0;
- }
- F0R(i, (int)t.size()){
- tri& c = t[i];
- int q = amt[c.ia][c.ib][c.ic];
- dp[i] = add(dp[i], mul(mul(choose(n-3, q), fac[q]), 6));
- F0R(j, n){
- if(j!=c.ia&&j!=c.ib&&j!=c.ic){
- if(inside(c, v[j])) continue;
- int A = c.ia, B = c.ib, C = c.ic;
- if(inside(tri(v[B], v[C], v[j]), v[A])) swap(A, C);
- else if(inside(tri(v[A], v[C], v[j]), v[B])) swap(B, C);
- if(inside(tri(v[A], v[B], v[j]), v[C])){
- int dif = amt[A][B][j]-q-1;
- dp[ind[A][B][j]] = add(dp[ind[A][B][j]], mul(dp[i], mul(choose(n-4-q, dif), fac[dif])));
- }
- }
- }
- }
- cout << dp.back() << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement