hdu 5738(扫描线)

来源:互联网 发布:python 类的使用 编辑:程序博客网 时间:2024/05/24 06:19
#include <bits/stdc++.h>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;#define LL long long#define pii pair<int,int>#define MP make_pair#define ls i << 1#define rs ls | 1#define md (ll + rr >> 1)#define lson ll, md, ls#define rson md + 1, rr, rs#define Pi acos(-1.0)#define mod 1000000007#define eps 1e-12#define inf 0x3f3f3f3f#define N 2010#define M 1200020int dcmp(double x){    if(fabs(x) < eps) return 0;    return x < 0 ? -1 : 1;}struct point{    int x, y, id;    double deg;    point(int _x = 0, int _y = 0, int _id = 0){        x = _x, y = _y, id = _id;        deg = atan2(y * 1.0, x * 1.0);    }    bool operator < (const point &b) const {        return x < b.x || x == b.x && y < b.y;    }    bool operator == (const point &b) const {        return x == b.x && y == b.y;    }};int n, a[N], id[N], pow2[N];point p[N], pp[N];int ans;void add(int &x, int y){    x += y;    if(x >= mod) x -= mod;    if(x < 0) x += mod;}bool cmp(point a, point b){    return a.deg < b.deg;}void gao(point p[], int m, int xx){    sort(p + 1, p + 1 + m, cmp);    for(int i = 1, k = 0; i <= m; ++i){        if(i > 1 && dcmp(p[i].deg - p[i-1].deg) == 0){            k += a[p[i-1].id];        }        else k = 0;         int x = (pow2[xx] - 1 + mod) % mod;        int y = (pow2[a[p[i].id]] - 1 + mod) % mod;        int z = pow2[k];        add(ans, 1LL * x * y % mod * z % mod);    }}int qpow(int x, int k){    int ret = 1;    while(k){        if(k & 1) ret = 1LL * ret * x % mod;        x = 1LL * x * x % mod;        k >>= 1;    }    return ret;}    int main(){    pow2[0] = 1;    for(int i = 1; i < N; ++i)        pow2[i] = pow2[i-1] * 2 % mod;    int cas;    scanf("%d", &cas);    while(cas--){        scanf("%d", &n);        for(int i = 1; i <= n; ++i)            scanf("%d%d", &p[i].x, &p[i].y);        sort(p + 1, p + 1 + n);        int cnt = 1;        p[cnt] = p[1], a[1] = 1;        for(int i = 2; i <= n; ++i){            if(p[i] == p[cnt]) a[cnt]++;            else{                p[++cnt] = p[i];                a[cnt] = 1;            }        }        n = cnt;        int sum = 0;        ans = 0;        for(int i = 1; i <= n; ++i){            if(a[i] >= 2){                add(sum, pow2[a[i]] - 1 - a[i]);            }            int tot = 0;            for(int j = 1; j <= n; ++j){                if(i == j) continue;                pp[++tot] = point(p[j].x - p[i].x, p[j].y - p[i].y, j);            }            gao(pp, tot, a[i]);        }        printf("%d\n", (int)(1LL * ans * qpow(2, mod-2) % mod + sum) % mod);    }    return 0;}
0 0