【虚树】hdu6161 Big binary tree

题意:一棵n个结点的完全二叉树,初始i号结点的权值为i。有两种操作:单点修改;询问经过某个结点的路径中,权值和最大的路径的权值和是多少。

修改的时候,暴力修改到根节点的路径上的点的f(x)即可。

跟虚树的思想只是有点点像而已,实际上不是一个东西啦。

队友的代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

struct nod{
int lx,d;
long long c;
}q[110000];

struct nod2{
int sum[40],s[40],l;
}ceng;
int ls[2800000],i,n,m,all,wei[40];
long long t[2800000],v[2800000];
char s[100];

int fen(int a)
{
    if (a==0) return 0;
    int l=1,r=all,mid;
    while (l!=r)
    {
        mid=(l+r)/2;
        if (ls[mid]>=a) r=mid; else l=mid+1;
    }
    return l;
}

void add(int a)
{
    while (a)
    {
        ls[++all]=a;
        a=a/2;
    }
}

void quchong()
{
    int l,r,now=0;
    l=1;
    while (l<=all)
    {
        r=l;
        while (r<=all && ls[l]==ls[r]) r++;
        ls[++now]=ls[l];
        l=r;
    }
    all=now;
}

long long getv(int d)
{
    if (d>n) return 0;
    int k=fen(d),c,y,ans;
    if (ls[k]==d) return t[k];
    y=d; c=0;
    while (y!=0)
    {
        c++;
        y=y/2;
    }
    if (d==ceng.s[c]) return ceng.sum[c];
    ans=0; y=d;
    while (y<=n)
    {
        ans+=y;
        y=y*2+1;
    }
    return ans;

}

void modify(int d,long long a)
{
    d=fen(d); v[d]=a;
    while (d!=0)
    {
        t[d]=max(getv(ls[d]*2),getv(ls[d]*2+1))+v[d];
        d=fen(ls[d]/2);
    }
}

void getceng(int d)
{
    int i;
    ceng.l=0;
    while (d)
    {
        ceng.s[++ceng.l]=d;
        d=d/2;
    }
    for (i=1;i<=ceng.l/2;i++) swap(ceng.s[i],ceng.s[ceng.l-i+1]);
    ceng.sum[ceng.l]=ceng.s[ceng.l];
    for (i=ceng.l-1;i>=1;i--) ceng.sum[i]=ceng.s[i]+ceng.sum[i+1];
}

long long getans(int d)
{
    long long ans,p,sum=0;
    int pre;
    d=fen(d); p=t[d];
    ans=getv(ls[d]*2)+getv(ls[d]*2+1)+v[d];
    pre=d; d=fen(ls[d]/2);
    while (d)
    {
        sum+=v[d];
        if (ls[d]*2==ls[pre]) ans=max(ans,p+sum+getv(ls[d]*2+1)); else ans=max(ans,p+sum+getv(ls[d]*2));
        pre=d;
        d=fen(ls[d]/2);
    }
    return ans;
}

void chushi()
{
    int i;
    for (i=all;i>=1;i--)
    {
        v[i]=ls[i];
        t[i]=max(getv(ls[i]*2),getv(ls[i]*2+1))+v[i];
    }
}

int main()
{
    wei[0]=1;
    for (i=1;i<=30;i++) wei[i]=wei[i-1]*2;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        all=0;
        getceng(n);
        for (i=1;i<=m;i++)
        {
            scanf("%s",&s);
            if (s[0]=='q')
            {
                scanf("%d",&q[i].d);
                q[i].lx=0;
            }
            if (s[0]=='c')
            {
                scanf("%d%lld",&q[i].d,&q[i].c);
                q[i].lx=1;
            }
            add(q[i].d);
        }
        sort(ls+1,ls+all+1);
        quchong();
        chushi();
        for (i=1;i<=m;i++)
        {
            if (q[i].lx==1) modify(q[i].d,q[i].c);
            if (q[i].lx==0) printf("%lld
",getans(q[i].d));
        }
    }
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/7414624.html