hdu 划分树

来源:互联网 发布:unity3d shader 涂色 编辑:程序博客网 时间:2024/05/16 05:35


题意:给您一个数列  然后再给你一区间    让你在这个区间里找一个数使区间里的所有数与这个数差的绝对值和最小   ,

思路:

  毫无疑问   这个数就是中位数(==可以推出来的)   对于区间是基数个  和偶数个  其实都一样 因为最后都约去了    :  假如x是所求的值     这个区间内比x小的有left个  比x大的有right个     其中left个的和为sum1    right个和位sum2    则所求为sum2-sum1       对于基数个与偶数个的问题只有left与right区别了   如果是奇数个则left==right  否则   left-right=1

这就好说了   如果不相等  也就是与最终结果差个x  。   其中sum1和left可以在查找的时候累加起来     这就就解决了!!!    


#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;int num[100010],tree[20][100010],cont[20][100010];__int64 sum[20][100010],f[100010];int build(int floot,int L,int R){    int mid=(L+R)/2;    int cc=mid-L+1;    int lstar=L,rstar=mid+1,i;    for(i=L;i<=mid;i++)    {        if(num[i]<num[mid]) cc--;    }    sum[floot][0]=0;        for(i=L;i<=R;i++)    {        if(i==L)         {            cont[floot][i]=0;        }        else         {            cont[floot][i]=cont[floot][i-1];        }        sum[floot][i]=sum[floot][i-1];        if(tree[floot][i]==num[mid])        {            if(cc)            {                cc--;                cont[floot][i]++;                sum[floot][i]+=tree[floot][i];                tree[floot+1][lstar++]=tree[floot][i];            }            else tree[floot+1][rstar++]=tree[floot][i];        }        else if(tree[floot][i]<num[mid])        {            cont[floot][i]++;            sum[floot][i]+=tree[floot][i];            tree[floot+1][lstar++]=tree[floot][i];        }        else        {            tree[floot+1][rstar++]=tree[floot][i];        }    }    if(L==R) return 0;    build(floot+1,L,mid);    build(floot+1,mid+1,R);    return 0;}__int64 ss;int c;int find(int floot,int L,int R,int left,int right,int k){    if(L==R) return tree[floot][L];    int mid=(L+R)/2;    int s1,s2;    if(L==left)    {        s1=0;        s2=cont[floot][right];    }        else     {        s1=cont[floot][left-1];        s2=cont[floot][right]-s1;    }    if(k<=s2)    {        return find(floot+1,L,mid,L+s1,L+s1+s2-1,k);    }    else    {        c+=s2;        ss+=sum[floot][right]-sum[floot][left-1];        return find(floot+1,mid+1,R,mid-L+1+left-s1,mid-L+1+right-s1-s2,k-s2);    }}int main(){    int n,m,i,j,T,d=1;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        f[0]=0;        for(i=1;i<=n;i++)        {            scanf("%d",&num[i]);            tree[1][i]=num[i];            f[i]=f[i-1]+num[i];        }        sort(num+1,num+1+n);        build(1,1,n);        int Q,left,right,k;        scanf("%d",&Q);        printf("Case #%d:\n",d++);        while(Q--)        {            scanf("%d%d",&left,&right);            left++;            right++;            ss=c=0;            k=(right-left+2)/2;            int t=find(1,1,n,left,right,k);            __int64 x=f[right]-f[left-1];            int p=right-left+1;            //printf("%I64d\n",(__int64)t*(c-(right-left+1-c))+f[right]-f[left-1]-ss-ss);              printf("%I64d\n",(x-ss-ss)+((__int64)t*(2*c-p)));        }        printf("\n");    }    return 0;}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 混合喂养的宝宝不吃奶粉怎么办 三个月的宝宝突然不吃奶粉怎么办 四个月宝宝拉绿屎推拿怎么办 三个月大的宝宝消化不良怎么办 婴儿大便常规正常的腹泻怎么办 宝宝十个月母乳不够吃怎么办 吃药上吐腹泻在3怎么办 房子买了新生儿户口怎么办 吃海鲜拉稀拉水怎么办 吃海鲜腹泻拉水怎么办 两个月宝宝不爱睡觉怎么办 2个月宝宝干呕怎么办 9个月宝宝拉稀的怎么办 宝宝拉肚子快一个月了怎么办 满月宝宝发烧38度怎么办 大人腹泻10天了怎么办 十个月宝贝拉水怎么办 十个月宝宝脱水哭闹怎么办 宝宝肠胃不好老是拉肚子怎么办 七个月的宝宝老是拉肚子怎么办 6个月宝宝拉肚子怎么办 没满月宝宝吐奶怎么办 八个月宝宝有点拉肚子怎么办 4个月宝宝拉水怎么办 2岁宝宝消化不好拉肚子怎么办 两岁宝宝老拉肚子怎么办 2岁宝宝拉肚子老不好怎么办 2岁宝宝一直拉肚子不好怎么办 5天新生儿拉稀水怎么办 4天新生儿拉稀水怎么办 新生儿40天拉稀水怎么办 一周多的宝宝拉肚子怎么办 出生半个月的宝宝拉肚子怎么办 刚出生几天的宝宝拉肚子怎么办 刚出生的宝宝拉肚子怎么办 出生八天的宝宝拉肚子怎么办 刚出生婴儿拉水怎么办 三岁宝宝一直吐怎么办 3岁宝宝一直吐怎么办 5个月宝宝一直吐怎么办 新生儿睡反了觉怎么办