hdu 4123 Bob’s Race

来源:互联网 发布:华中师范大学网络课程 编辑:程序博客网 时间:2024/05/22 14:16

题解:

三个模板的叠加:

求树中一个点的最远距离(DP)+最值(RMQ)+单调性

这个题值得注意的地方是:log函数很慢,需要预处理。

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;int n,m;const int maxn=51000;int max1[maxn],max2[maxn],rec1[maxn],rec2[maxn];int b[maxn];int f[maxn];int rmq_max[maxn][20],rmq_min[maxn][20];int q[maxn];int l[maxn],r[maxn];int flog[maxn];bool v[maxn];struct node{    int u,next,d;}a[maxn*10];int head[maxn];void dp(int x){    if(v[x])return;    v[x]=true;    bool flag=false;    //max1    for(int i=head[x];i!=-1;i=a[i].next)    if(!v[a[i].u])    {        flag=true;        dp(a[i].u);        if(max1[a[i].u]+a[i].d>=max1[x])        {            max2[x]=max1[x];            rec2[x]=rec1[x];            max1[x]=max1[a[i].u]+a[i].d;            rec1[x]=a[i].u;        }        else if(max1[a[i].u]+a[i].d>max2[x])        {            max2[x]=max1[a[i].u]+a[i].d;            rec2[x]=a[i].u;        }    }    if(!flag)max1[x]=0;}void dfs(int x,int father,int d){    v[x]=true;    if(x==1)f[x]=0;    else    {        if(rec1[father]!=x&&max1[father]!=-1)        f[x]=max1[father]+d;        else if(rec2[father]!=x&&max2[father]!=-1)        f[x]=max2[father]+d;        f[x]=max(f[x],f[father]+d);    }    for(int i=head[x];i!=-1;i=a[i].next)    if(!v[a[i].u])    {        dfs(a[i].u,x,a[i].d);    }}inline int getmax(int l,int r){    int x=flog[r-l+1];    return max(rmq_max[l][x],rmq_max[r+1-(1<<x)][x]);}inline int getmin(int l,int r){    int x=flog[r-l+1];    return min(rmq_min[l][x],rmq_min[r+1-(1<<x)][x]);}int main(){    for(int i=1;i<=maxn-1;i++)    flog[i]=log2(i);    while(1)    {        scanf("%d%d",&n,&m);if(n==0 && m==0)break;        for(int i=1;i<=n;i++)        head[i]=-1;        int num=0;        for(int i=1;i<=n-1;i++)        {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            num++;a[num].u=y;a[num].d=z;a[num].next=head[x];head[x]=num;            num++;a[num].u=x;a[num].d=z;a[num].next=head[y];head[y]=num;        }        //pre        memset(rec1,0,sizeof(rec1));        memset(rec2,0,sizeof(rec2));        memset(max1,-1,sizeof(max1));        memset(max2,-1,sizeof(max2));        memset(v,false,sizeof(v));        dp(1);        memset(f,-1,sizeof(f));        memset(v,false,sizeof(v));        dfs(1,0,0);        for(int i=1;i<=n;i++)        b[i]=max(max1[i],f[i]);        //pre        for(int i=1;i<=n;i++)        {            rmq_max[i][0]=b[i];            rmq_min[i][0]=b[i];        }        for(int j=1;j<=flog[n];j++)        {            for(int i=1;i<=n+1-(1<<j);i++)            {                rmq_max[i][j]=max(rmq_max[i][j-1],rmq_max[i+(1<<(j-1))][j-1]);                rmq_min[i][j]=min(rmq_min[i][j-1],rmq_min[i+(1<<(j-1))][j-1]);            }        }        //        for(int i=1;i<=m;i++)        {            int lim;            scanf("%d",&lim);            int l=1,r=1,ans=0;            while(r<=n)            {                int mx=getmax(l,r);                int mi=getmin(l,r);                if(mx-mi<=lim)                {                    ans=max(ans,r-l+1);                    r++;                }                else                    l++;            }            printf("%d\n",ans);        }        //do    }    return 0;}

原创粉丝点击