zoukankan      html  css  js  c++  java
  • hdu 3473 裸的划分树

    思路:

    用Sum[dep][i]记录从tree[po].l到i中进入左子树的和。

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define Maxn 100010
    #define inf 0x7fffffff
    #define lowbit(x) (x&(-x))
    #define lson(x) (x<<1)
    #define rson(x) ((x<<1)|1)
    #define mid ((tree[po].l+tree[po].r)>>1)
    using namespace std;
    struct Tree{
        int l,r;
    }tree[Maxn*4];
    __int64 Sum[20][Maxn],sum[Maxn];
    __int64 lnum,lsum;
    int sorted[Maxn];
    int val[20][Maxn],toLeft[20][Maxn],n;
    void BuildTree(int l,int r,int dep,int po)
    {
        tree[po].l=l,tree[po].r=r;
        if(l==r) return ;
        int same=mid-l+1,i;
        for(i=l;i<=r;i++)
            if(val[dep][i]<sorted[mid])
                same--;
        int lpos=l,rpos=mid+1;
        for(i=l;i<=r;i++)
        {
            if(i==l)
                toLeft[dep][i]=0;
            else
                toLeft[dep][i]=toLeft[dep][i-1];
            Sum[dep][i]=Sum[dep][i-1];
            if(val[dep][i]<sorted[mid])
               Sum[dep][i]+=(__int64)val[dep][i],toLeft[dep][i]++,val[dep+1][lpos++]=val[dep][i];
            else
                if(val[dep][i]>sorted[mid])
                val[dep+1][rpos++]=val[dep][i];
            else
                if(same)
                Sum[dep][i]+=(__int64)val[dep][i],toLeft[dep][i]++,val[dep+1][lpos++]=val[dep][i],same--;
                else
                val[dep+1][rpos++]=val[dep][i];
        }
        BuildTree(l,mid,dep+1,lson(po));
        BuildTree(mid+1,r,dep+1,rson(po));
    }
    int query(int l,int r,int k,int dep,int po)
    {
        if(l==r)
            return val[dep][l];
        int vd,invd;
        if(l==tree[po].l)
            vd=toLeft[dep][r],invd=0;
        else
            vd=toLeft[dep][r]-toLeft[dep][l-1],invd=toLeft[dep][l-1];
        if(vd>=k){
            int newl=tree[po].l+invd;
            int newr=tree[po].l+vd+invd-1;
            return query(newl,newr,k,dep+1,lson(po));
        }
        else{
            int ss=l-tree[po].l-invd;
            int s=r-l+1-vd;
            int newl=mid+ss+1;
            int newr=mid+ss+s;
            lnum+=vd;
            lsum+=Sum[dep][r]-Sum[dep][l-1];
            return query(newl,newr,k-vd,dep+1,rson(po));
        }
    }
    int main()
    {
        int m,i,j,k,s,t,T,Case=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(i=1;i<=n;i++)
            {
                scanf("%d",&val[0][i]);
                sorted[i]=val[0][i];
                sum[i]=sum[i-1]+(__int64)val[0][i];
            }
            sort(sorted+1,sorted+1+n);
            BuildTree(1,n,0,1);
            __int64 temp;
            __int64 ans=0;
            scanf("%d",&m);
            printf("Case #%d:
    ",++Case);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&s,&t);
                s++,t++;
                lnum=lsum=0;
                k=(t-s+2)/2;
                temp=(__int64)query(s,t,k,0,1);
                //cout<<lnum<<" "<<temp<<" "<<lsum<<" "<<sum[t]<<" "<<k<<" "<<sum[s-1]<<endl;
                ans=lnum*temp-lsum+sum[t]-sum[s-1]-lsum-(t-s+2-k)*temp;
                printf("%I64d
    ",ans);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    数据结构实验2-迷宫
    离散实验4
    关系代数中的除法运算
    数据库中什么叫象集
    (转)汇编-补码
    2014022201
    20140222
    2014022101
    代码20140221
    代码20140215
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3248428.html
Copyright © 2011-2022 走看看