首页 > 代码库 > POJ3162 Walking Race

POJ3162 Walking Race

题解:

分为两部分,第一部分和SGU149一样。

第二个部分:给你一个数组,求最长的连续的一段子数组,使得该子数组中的最大值减去最小值不超过M

学到了新姿势。。。用2个单调队列去维护,o(n)时间就行了

具体的可以去看POJ上面的discuss。。

代码:

#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<cstdio>using namespace std;#define pb push_back#define mp make_pair#define se second#define fs first#define LL long long#define CLR(x) memset(x,0,sizeof x)#define MC(x,y) memcpy(x,y,sizeof(x))  #define SZ(x) ((int)(x).size())#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1 typedef pair<int,int> P;const double eps=1e-9;const int N=1e6+10;const int M=1e3+10;const LL mod=1000000007;const int INF=1e9+10;int n,m,cnt;int head[N];int down1[N],down2[N],up[N],Son[N],ans[N];int qmax[N],qmin[N];struct Edge{    int v,w,nxt;}edge[N*2];void Init(){    cnt=0;    memset(head,-1,sizeof(head));    memset(up,0,sizeof(up));}void AddEdge(int u,int v,int w){    edge[cnt].v=v;    edge[cnt].nxt=head[u];    edge[cnt].w=w;    head[u]=cnt++;}void dfs1(int u,int fa){    down1[u]=down2[u]=0;    for(int i=head[u];i!=-1;i=edge[i].nxt){        int v=edge[i].v;        int w=edge[i].w;        if(v==fa) continue;        dfs1(v,u);        down2[u]=max(down2[u],down1[v]+w);        if(down2[u]>down1[u]){            swap(down2[u],down1[u]);            Son[u]=v;        }    }}void dfs2(int u,int fa){    for(int i=head[u];i!=-1;i=edge[i].nxt){        int v=edge[i].v;        int w=edge[i].w;        if(v==fa) continue;        if(Son[u]!=v) up[v]=max(up[u],down1[u])+w;        else          up[v]=max(up[u],down2[u])+w;        dfs2(v,u);    }}void solve(){    int goal=0,i,j;    int f1,r1,f2,r2;    f1=r1=f2=r2=0;    for(i=1,j=1;j<=n;j++){        while(r1>f1&&ans[qmax[r1-1]]<=ans[j]) r1--;        qmax[r1++]=j;        while(r2>f2&&ans[qmin[r2-1]]>=ans[j]) r2--;        qmin[r2++]=j;        if(ans[qmax[f1]]-ans[qmin[f2]]>m){            goal=max(goal,j-i);            while(ans[qmax[f1]]-ans[qmin[f2]]>m){                i=min(qmax[f1],qmin[f2])+1;                while(r1>f1&&qmax[f1]<i) f1++;                while(r2>f2&&qmin[f2]<i) f2++;            }        }    }    goal=max(goal,j-i);    printf("%d\n",goal);}int main(){     scanf("%d%d",&n,&m);     Init();     for(int i=1;i<n;i++){         int x,y;         scanf("%d%d",&x,&y);         AddEdge(x,i+1,y);AddEdge(i+1,x,y);     }     dfs1(1,-1);     dfs2(1,-1);     for(int i=1;i<=n;i++) ans[i]=max(down1[i],up[i]);     solve();     return 0;}

 

POJ3162 Walking Race