hdu3015树状数组

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3015

题意:给定n组数,每组数有值x和值h,求n组数两两的val的总和。将所有x和所有h分别离散化(不去重)变成x‘和h‘,val(i,j)为abs(xi-xj)*min(hi,hj)。

如:

x,    h——>x‘,h‘

10,100——>1,1

50,500——>4,4

20,200——>3,3

20,100——>1,1

思路:只要把n*n优化成n*logn就可以过。

tip1:按照h‘的值sort,并动态加点,每次加的点如果是已加点中h‘最小的,那么min()中要取的值就为h‘

tip2:离散化但是不去重,不需要unique

tip3:关于abs()部分的处理,两棵树状数组,一棵统计数量,一棵统计sum。abs()值为(大于x‘的sum-大于x‘的数量*x‘)+(小于x‘的数量*x‘-小于x‘的sum)

tip4:res和sum树状数组均需要开long long

附上代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int C1[maxn],C2[maxn],n;
int lowbit(int x)
{
    return x&-x;
}
void add1(int x,int c)
{
    for(;x<=n;x+=lowbit(x))
        C1[x]+=c;
}
void add2(int x,int c)
{
    for(;x<=n;x+=lowbit(x))
        C2[x]+=c;
}
int query1(int x)
{
    int res=0;
    for(;x;x-=lowbit(x))
        res+=C1[x];
    return res;
};
long long query2(int x)
{
    long long res=0;
    for(;x;x-=lowbit(x))
        res+=C2[x];
    return res;
}
struct node
{
    int x,h;
}p[maxn];
bool cmp(node a,node b)
{
    if(a.h==b.h)return a.x>b.x;
    else return a.h>b.h;
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(C1,0,sizeof C1);
        memset(C2,0,sizeof C2);
        int x[maxn]={0},h[maxn]={0};
        for(int i=0;i<n;i++)scanf("%d%d",&p[i].x,&p[i].h),x[i]=p[i].x,h[i]=p[i].h;
        sort(x,x+n);
        sort(h,h+n);
        sort(p,p+n,cmp);
        long long res=0;
        for(int i=0;i<n;i++)
        {
            int tmpx=lower_bound(x,x+n,p[i].x)-x+1;
            int tmph=lower_bound(h,h+n,p[i].h)-h+1;
            //cout<<tmpx<<" "<<tmph<<endl;
            res+=1ll*tmph*(-1ll*tmpx*(query1(n)-query1(tmpx))+1ll*tmpx*query1(tmpx-1)+query2(n)-query2(tmpx)-query2(tmpx-1));
            add1(tmpx,1);
            add2(tmpx,tmpx);
        }
        printf("%lld\n",res);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/myrtle/p/11756459.html

时间: 2024-10-19 11:17:53

hdu3015树状数组的相关文章

hdu3015树状数组 poj1990的离散化版本

都是一类题目,推导调试比较烦,想出来还是不难的 /* 给定n个点对,按一维升序排序一次,每个点的序号为Di,按二维升序排序一次,每个点的序号为Hi 求sum{w(i,j)} w(i,j)=abs(Di-Dj)*min(Hi-Hj) 那么将所有的点按照H升序排列,两个树状数组,一个维护区间d的个数,一个维护区间d的总和 每个点的贡献值=树状数组中D小于其的+D大于其的abs 按升序遍历每个点后,将该点在树状数组中删掉 */ #include<bits/stdc++.h> using namesp

hdu3015 Disharmony Trees(树状数组+排序)

题目链接:点击打开链接 解题思路: 1.首先对x和高度h分别从小到大排序记录排名 2.然后对高度h按从大到小排序(保证当前要计算的树的高度是所有已经遍历的树中最小高度,便于计算S=min(h1,h2)) 3.循环遍历数组,每次遍历向树状数组C中t[i].rx位置增加t[i].rx,向树状数组C1中t[i].rx位置增加1 解析:C记录排名和,C1记录个数 所以以t[i].rh为最小值的点对的和为 t[i].rh*(sum(n)-sum(t[i].rx)-(LL)t[i].rx*(sum1(n)-

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

(POJ 3067) Japan (慢慢熟悉的树状数组)

Japan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29295   Accepted: 7902 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island with N cities on the East coas

【二维树状数组】See you~

https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A x y n1 :给格点(x,y)的值加n1 D x y n1: 给格点(x,y)的值减n1,如果现在格点的值不够n1,把格点置0 M x1 y1 x2 y2:(x1,y1)移动给(x2,y2)n1个 S x1 y1 x2 y2 查询子矩阵的和 [思路] 当然是二维树状数组 但是一定要注意:lowbi

Vijos P1066 弱弱的战壕【多解,线段树,暴力,树状数组】

弱弱的战壕 描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒[email protected][email protected]). 但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT).这样,永恒就可以从别的地方进攻摧毁战壕,从而消灭mx的部队. 战壕都有一个保护范围,同它的攻击

CF 313 DIV2 B 树状数组

http://codeforces.com/contest/313/problem/B 题目大意 给一个区间,问你这个区间里面有几个连续相同的字符. 思路: 表示个人用树状数组来写的...了解了树状数组的本质就行了. 当然用sum[r]-sum[l]也是可以的

Hdu5032 极角排序+树状数组

题目链接 思路:参考了题解.对询问进行极角排序,然后用树状数组维护一下前缀和即可. /* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; const int maxn=1010; const int maxm=10

Curious Robin Hood(树状数组+线段树)

1112 - Curious Robin Hood    PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 MB Robin Hood likes to loot rich people since he helps the poor people with this money. Instead of keeping all the money together he does another tri