您的位置:首页 > 其它

hdu6161Big binary tree-(树形dp+空间优化)

2017-08-24 20:05 330 查看
题解:经过这个点最长路径可能是这个点的左右子树的最大值得和加上这个点的值或者是以这个点为根下面叶子节点爬上来的最大值加上max(它往真正的根爬途中经过的结点的值加上另外一棵子树)

因为这个结点的值更新了只有影响到它上面那些节点的最大值所以只要把影响的那些节点的值记录一下,其他的结点的最大值根据它向下能向下几层向左取或者向右取就可以了。所以我们只要记录那些被影响的节点的值,其他的不记录到时候按照上面的方法搜索一下即可,这样空间复杂度就是0(mlogn)如果把每个值都记录的话这题空间不够

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cstdio>
using namespace std;
typedef long long int ll;
#define lson 2*x
#define rson 2*x+1
map<int,ll>v;
map<int,ll>f;
int n,m;
int deep(int x){
int ans = 0;
while(x<=n){
ans++;
x *= 2;
}
return ans;
}
ll dp(int x){
if(x>n) return 0;
if(f.count(x)) return f[x];
ll ans;
if(v.count(x))
ans = v[x];
else
ans = x;
if(deep(rson)==deep(lson))
ans += dp(rson);
else
ans += dp(lson);
return ans;
}
ll search(int x){
ll ans = dp(lson)+dp(rson);
if(v.count(x))
ans += v[x];
else
ans += x;
if(x==1)
return ans;
ll sum = dp(x);
int pre;
while(x>1){
pre = x;
x /= 2;
sum += v.count(x)?v[x]:x;
if(pre&1)
ans = max(sum+dp(lson),ans);
else
ans = max(sum+dp(rson),ans);
}
return max(ans,sum);
}
void change(int x,ll y){
v[x] = y;
f[x] = max(dp(lson),dp(rson))+y;
x /= 2;
while(x){
f[x] = max(dp(lson),dp(rson));
if(v.count(x))
f[x]+=v[x];
else
f[x]+=x;
x /= 2;
}
}
int main(){
char s[20];
while(scanf("%d%d",&n,&m)!=EOF){
f.clear();
v.clear();
while(m--){
int x;
ll y;
scanf("%s%d",s,&x);
if(s[0]=='q')
printf("%I64d\n",search(x));
else{
scanf("%I64d",&y);
change(x,y);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: