HZAU 1203 One Stroke(dfs+二分 Or 双指针)




题意:给你一棵二叉树,点有点权,每次往左或者往右走,求最长走的路,并且点权和小于k;

思路:官方题解,尺取,我的写法,树上二分,

   对于一条链,枚举每个点为终点,vector存该点到根节点的前缀和,二分一下即可;

   详见代码;

  HZAU 1203 One Stroke(dfs+二分 Or 双指针)_第1张图片

借鉴下网友代码!

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-4
#define bug(x)  cout<<"bug"<v;
void dfs(int x)
{
    int s=0,t=v.size()-1;
    int e=v.size()-1,ansq=-1;
    while(s<=e)
    {
        int mid=(s+e)>>1;
        if(v[t]-v[mid]<=k)
        {
            ansq=mid;
            e=mid-1;
        }
        else s=mid+1;
    }
    if(v[t]<=k)ans=max(ans,t+1);
    else ans=max(ans,t-ansq);
    int z=v[v.size()-1];
    if(x*2<=n)
    {
        v.push_back(z+a[x<<1]);
        dfs(x<<1);
        v.pop_back();
    }
    if(x*2+1<=n)
    {
        v.push_back(z+a[x<<1|1]);
        dfs(x<<1|1);
        v.pop_back();
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans=0;
        v.clear();
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        v.push_back(a[1]);
        dfs(1);
        if(ans)printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}







你可能感兴趣的:(二分,搜索--BFS,&,DFS,待整理文档)