zoukankan      html  css  js  c++  java
  • hdu3015,poj1990树状数组

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

    题意:给定n组数,每组数有值x和值h,求n组数两两的val的总和。将所有x和所有h分别离散化(不去重)变成x'和h',val(i,j)为abs(x'i-x'j)*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
    ",res);
        }
        return 0;
    }

    poj1990,一道类似的题

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    const int maxn=2e4+10;
    int n,C1[maxn],C2[maxn],maxp;
    struct node
    {
        int v,place;
    }p[maxn];
    bool cmp(node a,node b)
    {
        if(a.v==b.v)return a.place>b.place;
        else return a.v>b.v;
    }
    int lowbit(int x)
    {
        return x&-x;
    }
    void add1(int x,int c)
    {
        for(;x<=maxp;x+=lowbit(x))
            C1[x]+=c;
    }
    void add2(int x,int c)
    {
        for(;x<=maxp;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;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)scanf("%d%d",&p[i].v,&p[i].place),maxp=max(maxp,p[i].place);
        sort(p,p+n,cmp);
        long long res=0;
        for(int i=n-1;i>=0;i--)
        {
            //cout<<p[i].v<<" "<<p[i].place<<endl;
            res+=1ll*p[i].v*(query2(maxp)-query2(p[i].place)-p[i].place*(query1(maxp)-query1(p[i].place))+p[i].place*query1(p[i].place-1)-query2(p[i].place-1));
            add1(p[i].place,1);
            add2(p[i].place,p[i].place);
            //cout<<res<<endl;
        }
        printf("%lld
    ",res);
        return 0;
    }
  • 相关阅读:
    Sereja and Bottles-水题有点坑爹
    what we benefit from big data
    SwipeRefreshLayout与ViewPager滑动事件冲突解决
    java连接数据库核心代码
    spring mvc中实现csrf安全防御简记
    一题多解(八)—— 矩阵上三角(下三角)的访问
    面向对象举例(一) —— 顶点(vertex)、边(edge)与图(graph)
    面向对象举例(一) —— 顶点(vertex)、边(edge)与图(graph)
    Python 辨异 —— __init__ 与 __new__
    Python 辨异 —— __init__ 与 __new__
  • 原文地址:https://www.cnblogs.com/myrtle/p/11756459.html
Copyright © 2011-2022 走看看