首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。