zoukankan      html  css  js  c++  java
  • HZAU 1203 One Stroke(倍增)

    题目链接:http://acm.hzau.edu.cn/problem.php?id=1203

    【题意】给你一颗完全二叉树每个节点都有一个权值,然后要你从上往下找一条链,值得链上权值的和<K,且节点数最大。

    【分析】有两种做法:一种是在树上双指针,另一种是先求一下前缀和,当到i节点时前缀和<K,更新ans,当前缀和>K,倍增向上找

    使得前缀和<K的节点,更新ans。

    #include <bits/stdc++.h>
    #define inf 100000000
    #define met(a,b) memset(a,b,sizeof a)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    typedef long long ll;
    using namespace std;
    const int N = 1e6+5;
    const int M = 4e5+5;
    int n,m,ans;
    int a[N];
    int sum[N],fa[N][22],dep[N];
    void dfs(int u,int f){
        if(u>n)return;
        sum[u]=sum[f]+a[u];
        dep[u]=dep[f]+1;
        fa[u][0]=f;
        for(int i=1;i<22;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
        if(sum[u]<=m)ans=max(ans,dep[u]);
        else {
            int v=u;
            for(int i=21;i>=0;i--){
                if(sum[u]-sum[fa[v][i]]<=m){
                    ans=max(ans,dep[u]-dep[fa[v][i]]);
                    v=fa[v][i];
                }
            }
        }
        dfs(u*2,u);
        dfs(u*2+1,u);
    }
    int main() {
        int T,op,x,y,v;
        scanf("%d",&T);
        for(int cas=1;cas<=T;cas++){
            met(fa,0);
            ans=0;
            met(sum,0);
            met(dep,0);
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            dfs(1,0);
            printf("%d
    ",ans==0?-1:ans);
        }
        return 0;
    }
  • 相关阅读:
    applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.
    HTML
    c# Path路径类
    C# 继承
    C# 结构体
    c# 类
    c#方法
    wpf开源控件MahApps.Metro
    c#数组类型
    c#类型转换
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6754569.html
Copyright © 2011-2022 走看看