糯米

TI DaVinci, gstreamer, ffmpeg
随笔 - 167, 文章 - 0, 评论 - 47, 引用 - 0
数据加载中……

POJ 1990 MooFest 树状数组

思路:
开四个树状数组。。
arr_x,arr_y,arr_xy,arr_cnt
分别统计y轴下:x的和、y的和、x*y的和、点的个数。
把点按照x排序,x越大的点出现得越晚。
从前往后推,每出现一个新的点的时候:
Step1,将该点加入到四个数组中。
Step2,对于高于它的点,面积增量为 x*sum(y) - sum(x*y)。
Step3,对于低于它的点,面积增量为 sum(y) * (cnt * x - sum(x))
最终得出结果。复杂度O(NlgN)。代码 63ms。

注意:
需要用int64保存数组元素

#include <stdio.h>

#define MAX_X 20032
#define MAX_Y 20032

int cow[MAX_X], left, top, N;
__int64 arr_x[MAX_Y], arr_y[MAX_Y], arr_xy[MAX_Y], arr_cnt[MAX_Y];

__inline 
int lowbit(int i)
{
    
return i & (i ^ (i - 1));
}


__inline __int64 sum(__int64 
*arr, int i)
{
    __int64 s;
    
    
for (s = 0; i; i -= lowbit(i))
        s 
+= arr[i];
    
return s;
}


__inline 
void insert(__int64 *arr, int i, __int64 val)
{
    
for (; i <= top; i += lowbit(i))
        arr[i] 
+= val;
}


int main()
{
    
int i, x, y;
    __int64 s, sx, sy, sxy, c;

    freopen(
"e:\\test\\in.txt""r", stdin);

    scanf(
"%d"&N);
    left 
= MAX_X;
    
for (i = 0; i < N; i++{
        scanf(
"%d%d"&y, &x);
        
if (x < left)
            left 
= x;
        
if (y > top)
            top 
= y;
        cow[x] 
= y;
    }


    s 
= 0;
    x 
= left - 1;
    
for (i = 0; i < N; i++{
        
for (x++!cow[x]; x++);
        y 
= cow[x];
        insert(arr_x, y, x);
        insert(arr_y, y, y);
        insert(arr_xy, y, x 
* y);
        insert(arr_cnt, y, 
1);
        c 
= sum(arr_cnt, y - 1);
        sx 
= sum(arr_x, y - 1);
        s 
+= c*x*- sx*y;
        sy 
= sum(arr_y, top) - sum(arr_y, y - 1);
        sxy 
= sum(arr_xy, top) - sum(arr_xy, y - 1);
        s 
+= x*sy - sxy;
    }


    printf(
"%I64d\n", s);

    
return 0;
}

posted on 2010-03-14 17:39 糯米 阅读(385) 评论(0)  编辑 收藏 引用 所属分类: POJ


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理