hdu 3473 Minimum Sum(划分树)

375MS 30512K
#include <stdio.h>
#include <algorithm>

 

using namespace std;

typedef long long LL;

#define MAXN 100005
#define MAXLOG 20

int sorted[MAXN],seq[MAXLOG][MAXN],toleft[MAXLOG][MAXN];
LL total[MAXN],sum_toleft[MAXLOG][MAXN];

struct STNode
{
    int l,r;
};
STNode node[MAXN*3];

void build(int l,int r,int idx,int d)
{
    node[idx].l = l;
    node[idx].r = r;
    if(l == r) return;
    int mid = (l+r)/2,lsame,i;
    lsame = mid - l + 1;
    for(i=l; i<=r; i++)
        if(seq[d][i] < sorted[mid]) lsame--;
    int lpos=l,rpos=mid+1;
    for(i=l; i<=r; i++)
    {
        if(i == l)
        {
            toleft[d][i] = 0;
            sum_toleft[d][i] = 0;
        }
        else
        {
            toleft[d][i] = toleft[d][i-1];
            sum_toleft[d][i] = sum_toleft[d][i-1];
        }

        if(seq[d][i] < sorted[mid])
        {
            toleft[d][i]++;
            seq[d+1][lpos++] = seq[d][i];
            sum_toleft[d][i] += seq[d][i];
        }
        else if(seq[d][i] > sorted[mid]) seq[d+1][rpos++] = seq[d][i];
        else
        {
            if(lsame > 0)
            {
                lsame--;
                toleft[d][i]++;
                seq[d+1][lpos++] = seq[d][i];
                sum_toleft[d][i] += seq[d][i];
            }
            else seq[d+1][rpos++] = seq[d][i];
        }
    }
    build(l,mid,idx*2,d+1);
    build(mid+1,r,idx*2+1,d+1);
}

LL num_lessMid,sum_lessMid;//设查询区间为[i,j],该区间中位数为m,则它们分别为小于等于m的个数及和
int query(int l,int r,int k,int idx,int d)
{
    if(l == r) return seq[d][l];
    int ss,s;
    LL lsumTmp; //[l,r]小于中位数的和,只是临时的,真正记录的是sum_lessMid
    if( l == node[idx].l)
    {
        ss = 0;
        s = toleft[d][r];

        lsumTmp = sum_toleft[d][r];
    }
    else
    {
        ss = toleft[d][l-1];
        s = toleft[d][r] - ss;

        lsumTmp = sum_toleft[d][r] - sum_toleft[d][l-1];
    }
    int newl,newr;
    if(s >= k)
    {
        newl = node[idx].l + ss;
        newr = newl + s - 1;
        return query(newl,newr,k,idx*2,d+1);
    }
    else
    {
        int bb,b;
        bb = l - node[idx].l - ss;
        b = r - l + 1 - s;
        newl = node[idx*2+1].l + bb;
        newr = newl + b - 1;

        num_lessMid += s;
        sum_lessMid += lsumTmp;

        return query(newl,newr,k-s,idx*2+1,d+1);
    }
}

LL ask(int l,int r)
{
    num_lessMid = sum_lessMid = 0;
    LL median = query(l,r,(r-l)/2+1,1,1);
    LL ans = median * num_lessMid - sum_lessMid;
    LL sum_greaterMid = total[r] - total[l-1] - sum_lessMid;
    ans += sum_greaterMid - median * ( r - l + 1 -num_lessMid );
    return ans;
}

int main()
{
    int T,cas,n,q,i,j;
    scanf("%d",&T);
    for(cas=1; cas<=T; cas++)
    {
        total[0]=0;
        scanf("%d",&n);
        for(i=1; i<=n; i++)
        {
            scanf("%d",&sorted[i]);
            seq[1][i]=sorted[i];
            total[i]=total[i-1]+sorted[i];
        }
        sort(sorted+1,sorted+n+1);
        build(1,n,1,1);
        scanf("%d",&q);
        printf("Case #%d:\n",cas);
        while(q--)
        {
            scanf("%d %d",&i,&j);
            printf("%I64d\n",ask(i+1,j+1));
        }
        printf("\n");
    }
    return 0;
}

posted @ 2010-09-05 22:29  菜到不得鸟  阅读(299)  评论(0)    收藏  举报