HDU 4311 树状数组+二分

题意:给出10W个点,找出一个点使得每点按网格走到它的步数和最小,求最小步数和。每步这么走Eg: (x,y) can be reached from (x-1,y), (x+1,y), (x, y-1), (x, y+1).。

a点到达b点的步数为abs(b.x-a.x)+abs(b.y-a.y) 那么a点到所有点的步数和为abs(pi.x-a.x)+abs(pi.y-ay)所以按照从小到大的顺序吧x,y的值排序,二分查找a.x a.y在数组中的位置,就是给上面那个求和在打开就变成abs(numx*ax-sumpi.x(1~numx))+abs(pi.x(numx+1~n)-(n-numx)*a.x)就是x的和 同理求出y的和就可以了意思就是这样

 ans=(x1+x2+x3+...+xn)-n*xi+(y1+y2+...+yn)-n*yi; 不过需要考虑大小关系

(括号里面的sum部分可以用树状数组、线段树来维护)

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 100005
long long treex[maxn<<1],treey[maxn<<1],datax[maxn],datay[maxn],sumx,sumy;
struct cor
{
    long long x,y;
} data[maxn];
int n;
inline int Lowbit(int x)
{
    return x&(-x);
}
inline void Update(int pos,long long val,long long *tree)
{
    while(pos<=maxn)
        tree[pos]+=val,pos+=Lowbit(pos);
}
inline long long Query(int x,long long *tree)
{
    long long sum=0;
    while(x>0)
        sum+=tree[x],x-=Lowbit(x);
    return sum;
}
inline int find(long long val,long long *data)
{
    int l=0,r=n-1,mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(val==data[mid])
            return mid+1;
        else if(val<data[mid])
            r=mid-1;
        else
            l=mid+1;
    }
}
long long ab(long long a)
{
    return a<0?-a:a;
}
long long getans(cor a)
{
    long long sum,nowx,nowy;
    int numx,numy;
    numx=find(a.x,datax),numy=find(a.y,datay);
    nowx=Query(numx,treex),nowy=Query(numy,treey);
    sum=ab((long long)numx*a.x-nowx)+ab(sumx-nowx-(long long)(n-numx)*a.x)+ab((long long)numy*a.y-nowy)+ab(sumy-nowy-(long long)(n-numy)*a.y);
    return sum;
}
int main()
{
    int t;
    long long ans;
    scanf("%d",&t);
    while(t--)
    {
        sumx=sumy=0;
        memset(treex,0,sizeof(treex));
        memset(treey,0,sizeof(treey));
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%I64d%I64d",&data[i].x,&data[i].y),
                datax[i]=data[i].x,datay[i]=data[i].y,
                    sumx+=data[i].x,sumy+=data[i].y;
        sort(datax,datax+n);
        sort(datay,datay+n);
        for(int i=0; i<n; i++)
            Update(i+1,datax[i],treex),Update(i+1,datay[i],treey);
        ans=1e17;
        for(int i=0; i<n; i++)
            ans=min(ans,getans(data[i]));
        printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2024-08-18 07:35:30

HDU 4311 树状数组+二分的相关文章

HDU 1541 树状数组

题目意思就是说,给你一张star maps,每个star有自己的level,level是这样计算的:(Let the level of a star be an amount of the stars that are not higher and not to the right of the given star.)统计这个star左下角star的个数,就是这个star的level.现在要你总计图中level从0到N-1的star分别有多少个. 如入是按照X Y Y的递增顺序输入的 Y相同时

hdu 1556 Color the ball 树状数组

    最基本的树状数组,成段更新,感觉只要构造的时候保证两端平衡,即对后面非更新地方无影响即可,所以这题是a++ (b+1)--    温习了下快速IO,速度果然提升1倍 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #

HDOJ/HDU 1556 Color the ball(树状数组)

Problem Description N个气球排成一排,从左到右依次编号为1,2,3-.N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗? Input 每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N

树状数组专题【完结】

1 国外的论文点击打开链接 2 我的总结点击打开链接 任何能够造成树状数组下表为0的操作都会使得程序TLE,这是个很重要的地方! 第一题 poj 2299 Ultra-QuickSort 点击打开poj 2299 思路: 离散化+树状数组 分析: 1 题目的意思就是要求逆序数对 2 题目的输入个数有500000的规模但是每个数的最大值为999999999,因此我们需要离散化这些数据 3 对于数据9 1 0 5 4我们离散化成5 2 1 4 3 那么对于输入一个树a[i]我们去求一下它的离散化后的

js用闭包遍历树状数组的方法

 这篇文章主要介绍了js中用闭包遍历树状数组的方法,需要的朋友可以参考下 做公司项目时,要求写一个方法,方法的参数为一个菜单数组集合和一个菜单id,菜单数组的格式为树状json,如下面所示: 代码如下:[{"id":28,"text":"公司信息","children":[        {"id":1,"text":"公司文化"},        {"id

[php]运用变量引用实现一维数组转多维树状数组

/** * 运用 变量引用 实现 一维数组 转 多维树状数组 * @param $array * @param array $options = ['id'=>'id', 'pid'=>'pid', 'sub'=>'_sub', 'root'=>0] * @return array */ public static function array2Tree($array, $options = []) { /** merge Options */ $opt = array_merge

poj 2352 Stars 树状数组

     统计x之前出现数字的次数,线段树和树状数组都可以,但明显树状数组更简洁 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring&g

poj2481 树状数组

排序后类似stars, 用树状数组. 注意两个数组都要memset和去重 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; struct data{ int s, e, i; friend bool operator <(data a, data b){ if (a.e != b.e) return a.e > b.e; else return a.s&l

树状数组

                                                     1 一维树状数组   1 什么是树状数组        树状数组是一个查询和修改复杂度都为log(n)的数据结构,假设数组A[1..n],那么查询A[1]+...+A[n]的时,间是log级别的,而且是一个在线的数据结构.   2 树状数组作用        我们经常会遇到动态连续和查询问题,给定n个元素A[1~N],让我们求sum[L,R] = A[L]+...+A[R],或者更改A[i]