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

来源:互联网 发布:java图片压缩指定大小 编辑:程序博客网 时间:2024/06/05 18:49




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

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

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

   详见代码;

  

借鉴下网友代码!

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<cstdio>#include<cmath>#include<string>#include<queue>#include<algorithm>#include<stack>#include<cstring>#include<vector>#include<list>#include<set>#include<map>using namespace std;#define ll long long#define pi (4*atan(1.0))#define eps 1e-4#define bug(x)  cout<<"bug"<<x<<endl;const int N=1e6+10,M=1e6+10,inf=2147483647;const ll INF=1e18+10,mod=2147493647; ///数组大小int n,ans,k,a[N];vector<int>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;}







0 0
原创粉丝点击