[Codeforces-div.1 68D] Half-decay tree

[Codeforces-div.1 68D] Half-decay tree

试题分析

增加显然是(log)的。
由于某一些叶子结点的答案是一样的,所以我们可以考虑一次性求解。
容易想到一个非常优秀的剪枝:当(sz_kleq x)时,直接返回,其中x为上面的联通块最大sz。
为什么复杂度是对的呢?发现只有当(sz_k> x)的时候我们会继续递归,那么也就意味着另一边一定会(return),所以总体复杂度是(log)级别的。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<algorithm>
 
using namespace std;
#define LL long long
#define ls (k<<1)
#define rs (k<<1|1) 
 
inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const int INF = 2147483600;
const int MAXN = 100010;
 
int Q,H; map<int,int> sz; char str[11];
inline double calc(int k,int x){
    if(sz[k] <= x) return x;
    return 0.5*(calc(ls,max(x,sz[k]-sz[ls]))+calc(rs,max(x,sz[k]-sz[rs])));
}
 
int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    Q=read(),H=read(); while(H--){
        scanf("%s",str+1); if(str[1]=='a'){
            int k=read(),x=read(); while(k) sz[k]+=x,k>>=1;
        } else printf("%.10lf
",calc(1,0));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/wxjor/p/9520102.html