Big binary tree
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 139 Accepted Submission(s): 42
Problem Description
You are given a complete binary tree with n nodes. The root node is numbered 1, and node x's father node is ⌊x/2⌋ . At the beginning, node x has a value of exactly x. We define the value of a path as the sum of all nodes it passes(including two ends, or one if the path only has one node). Now there are two kinds of operations:
1. change u x Set node u's value as x(1≤u≤n;1≤x≤10^10)
2. query u Query the max value of all paths which passes node u.
Input
There are multiple cases.
For each case:
The first line contains two integers n,m(1≤n≤10^8,1≤m≤10^5), which represent the size of the tree and the number of operations, respectively.
Then m lines follows. Each line is an operation with syntax described above.
For each case:
The first line contains two integers n,m(1≤n≤10^8,1≤m≤10^5), which represent the size of the tree and the number of operations, respectively.
Then m lines follows. Each line is an operation with syntax described above.
Output
For each query operation, output an integer in one line, indicating the max value of all paths which passes the specific node.
Sample Input
6 13 query 1 query 2 query 3 query 4 query 5 query 6 change 6 1 query 1 query 2 query 3 query 4 query 5 query 6
Sample Output
17 17 17 16 17 17 12 12 12 11 12 12
Source
题解:由于n比较大,所以只存修改过的点,每次询问要枚举当前点p到根节点之间的所有点,取它的左子树和右子树的一条链作为答案,取最大值,更新则要从p到根节点都更新一下
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#define N 100005
using namespace std;
typedef long long ll;
const int INF=1e15+7;
map<ll,ll>mp,a;
ll n;
ll get(ll p)
{
ll ans1=0,x=p,ans2=0;
while(p<=n){
ans1+=p;
p=p*2+1;
}
ll t=n,f=0;
while(t){
ans2+=t;
if(t==x){
f=1;
break;
}
t>>=1;
}
if(f)return max(ans1,ans2);
return ans1;
}
int main()
{
int m;
while(~scanf("%lld%d",&n,&m))
{
mp.clear();
a.clear();
char c[10];
ll p;
while(m--)
{
scanf("%s%lld",c,&p);
if(c[0]=='q')
{
ll ans=0,x1,x2,x3;
x1=mp[p<<1]?mp[p<<1]:get(p<<1);
x2=mp[p<<1|1]?mp[p<<1|1]:get(p<<1|1);
x3=a[p]?a[p]:p;
ans=x1+x2+x3;
ll pre=mp[p]?mp[p]:get(p);
while(p>1)
{
x1=a[p/2]?a[p/2]:p/2;
if(p&1)x2=mp[p-1]?mp[p-1]:get(p-1);
else x2=mp[p+1]?mp[p+1]:get(p+1);
ans=max(ans,pre+x1+x2);
pre+=x1;
p>>=1;
}
printf("%lld\n",ans);
}
else {
ll x1,x2,x3;
scanf("%lld",&a[p]);
while(p){
x1=mp[p<<1]?mp[p<<1]:get(p<<1);
x2=mp[p<<1|1]?mp[p<<1|1]:get(p<<1|1);
x3=a[p]?a[p]:p;
mp[p]=max(x1,x2)+x3;
p>>=1;
}
}
}
}
return 0;
}