hdu 5448 Marisa’s Cake(几何+凸包)

来源:互联网 发布:彩虹秒赞源码2017破解 编辑:程序博客网 时间:2024/06/09 07:11

题目链接:hdu 5448 Marisa’s Cake

解题思路

这题和zoj 3871 Convex Hull有点像,不过点数比较大,不能接受o(n2)的算法。但是题目给定的是一个凸包,所以可以通过化简,在o(n)的复杂度内计算出答案。

首先,对于一个三角形ABC

SABC=fA×fB+fB×fC+fC×fA(fii

那么对于i和j两点,只需要计算fi×fjfj×fi对ans的贡献值是多少即可。

ans=i=1nj=1i1((2ij11)×fi×fj+(2ni+j11)×fj×fi)

ans=i=1nj=1i1(2ij1×fi×fjfi×fj+2ni+j1×fj×fifj×fi)

ans=i=1nj=1i1(2ij1×fi×fj+2ni+j1×fj×fi)

ans=i=1n(2i1fi×j=1i1(2jfj)+j=1i1(2jfj)×2ni1fi)

在过程中维护i1j=1(2jfj)i1j=1(2jfj)

代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100005;const int mod = 1e9 + 7;struct Point {    int x, y;    Point(int x = 0, int y = 0): x(x), y(y) {}    void read () { scanf("%d%d", &x, &y); }    int operator * (const Point& u) { return (1LL * x * u.y % mod - 1LL * y * u.x % mod + mod) % mod; }    Point operator * (const int u) { return Point(1LL * u * x % mod, 1LL * u * y % mod); }    Point operator + (const Point& u) { return Point((x+u.x)%mod, (y+u.y)%mod); }};int N, mul[maxn], inv[maxn];int mul_mod(ll x, int n, int mod) {    int ret = 1;    while (n) {        if (n&1) ret = x * ret % mod;        x = x * x % mod;        n >>= 1;    }    return ret;}int main () {    mul[0] = inv[0] = 1;    for (int i = 1; i < maxn; i++) mul[i] = 2 * mul[i-1] % mod;    ll inv2 = mul_mod(2, mod-2, mod);    for (int i = 1; i < maxn; i++) inv[i] = inv2 * inv[i-1] % mod;    int cas;    scanf("%d", &cas);    while (cas--) {        int ans = 0;        scanf("%d", &N);        Point fi, fg, fh;        for (int i = 1; i <= N; i++) {            fi.read();            ans = (ans + 1LL * mul[i-1] * (fi * fh) % mod) % mod;            ans = (ans + 1LL * (i==N?inv2:mul[N-i-1]) * (fg * fi) % mod) % mod;            fg = fg + fi * mul[i];            fh = fh + fi * inv[i];        }        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击