zoukankan      html  css  js  c++  java
  • 线段树——51nod1593&CF515E 公园晨跑

    Description

    luogu传送门
    51nod传送门

    有一只猴子,他生活在一个环形的公园里。有(n)棵树围绕着公园。第(i)棵树和第(i+1)棵树之间的距离是(d_i),而第(n)棵树和第一棵树之间的距离是(d_n)。第i棵树的高度是(h_i)

    这只猴子每天要进行晨跑。晨跑的步骤如下:
    ·他先选择两棵树;
    ·然后爬上第一棵树;
    ·再从第一棵树上下来,接着围绕着公园跑(有两个可能的方向)到第二棵树,然后爬上第二棵树;
    ·最后从第二棵树上下来。

    但是有一些小孩会在连续的一些树上玩耍。所以猴子不能经过这些树。

    比如现在猴子选择的第(x)棵和第(y)棵树,那么该早晨他消耗的能量是 $2(h_x+h_y)+dist(x,y) $。由于某一条路径是被小孩子占据的,所以他只能跑另外一条,因此 (dist(x,y)) 是确定的。

    现在给出第i天,孩子们会在第(a_i)棵树和 (b_i) 棵树之间玩耍。具体的,如果(a_ileq b_i),那么孩子玩耍的区间就是([a_i,b_i]),否则孩子玩耍的区间就是([a_i,n]⋃[1,b_i])

    请帮助这只猴子找出两棵树,让他晨跑的时候他能够消耗最大的能量。

    输入
    单组测试数据。
    第一行有两个整数(n)(m)((3leq nleq 10^5,1leq mleq 10^5)),表示树的数目,以及猴子跑步的天数。
    第二行有(n)个整数(d_1,d_2,...,d_n (1leq d_ileq 10^9)),表示树之间的距离。
    第三行有(n)个整数(h_1,h_2,...,h_n (1leq h_ileq 10^9)),表示树的高度。
    接下来(m)行,第一行有两个整数 (a_i)(b_i)((1leq a_i,b_ileq n)),描述每一天孩子玩耍的区间。输入保证至少有两个棵树孩子不会进行玩耍,这样猴子每天都可以晨跑了。
    输出
    对于每一天,输出猴子消耗的最大能量。

    输入样例
    5 3
    2 2 2 2 2
    3 5 2 1 4
    1 3
    2 2
    4 5

    输出样例
    12
    16
    18

    Solution

    注意到计算消耗能量的式子:(2(h_x+h_y)+dist(x,y)),设(g_i)为第(i)棵树到第一棵树的距离,那么式子可以转化成(-2h_y+g_y+2h_x-g_x(x<y)),这样(x)(y)是不互相影响的,就可以寻找一个区间里(2h_i+g_i)的最大值和(-2h_i-g_i)的最小值求解。将环复制一遍变成链,用线段树维护即可。

    对于一个区间的最大值和最小值可能相同的情况,分别询问最大值对应的次小值和最小值对应的次大值然后取max即可

    Code

    #include<iostream>
    #include<cstdio>
    #include<utility>
    #define int long long
    #define mk make_pair
    #define fi first
    #define se second
    using namespace std;
    const int N=6e5+5,inf=1e18;
    int n,m,d[N],h[N],sum[N];
    
    struct Seg {
    #define lc (k<<1)
    #define rc (k<<1|1)
    #define mid ((l+r)>>1)
    	int mx[N<<2],c[N<<2][2],mn[N<<2];
    
    	inline void build (int k,int l,int r) {
    		if (l==r) {
    			mn[k]=sum[l]-2*h[l];
    			mx[k]=sum[l]+2*h[l];
    			c[k][0]=c[k][1]=l;
    			return;
    		}
    		build(lc,l,mid);
    		build(rc,mid+1,r);
    		mx[k]=max(mx[lc],mx[rc]);c[k][0]= mx[lc] > mx[rc] ? c[lc][0] : c[rc][0];
    		mn[k]=min(mn[lc],mn[rc]);c[k][1]= mn[lc] < mn[rc] ? c[lc][1] : c[rc][1];
    	}
    	
    	inline pair<int,int> querymx (int k,int l,int r,int x,int y) {
    		if (x>y)	return mk(-inf,-inf);
    		if (x<=l&&r<=y) return mk(mx[k],c[k][0]);
    		pair<int,int> res=mk(-inf,0);
    		if (x<=mid)	res=max(res,querymx(lc,l,mid,x,y));
    		if (y>mid)	res=max(res,querymx(rc,mid+1,r,x,y));
    		return res;
    	}
    
    	inline pair<int,int> querymn (int k,int l,int r,int x,int y) {
    		if (x>y)	return mk(inf,inf);
    		if (x<=l&&r<=y) return mk(mn[k],c[k][1]);
    		pair<int,int> res=mk(inf,n*2+1);
    		if (x<=mid)	res=min(res,querymn(lc,l,mid,x,y));
    		if (y>mid)	res=min(res,querymn(rc,mid+1,r,x,y));
    		return res;
    	}
    #undef lc
    #undef rc
    #undef mid
    }T;
    
    inline int Abs (int x) {return x<0 ? -x : x;}
    
    inline int ask (int x,int y) {
    //	cout<<x<<" "<<y<<endl;
    	int a=T.querymx(1,1,n<<1,x,y).se;
    	int b=T.querymn(1,1,n<<1,x,y).se;//cout<<a<<" "<<b<<endl;
    	if (a!=b)	return h[a]*2+h[b]*2+Abs(sum[a]-sum[b]);
    	int A,B;
    	A=max(T.querymx(1,1,n<<1,x,a-1),T.querymx(1,1,n<<1,a+1,y)).se;
    	B=min(T.querymn(1,1,n<<1,x,b-1),T.querymn(1,1,n<<1,b+1,y)).se;
    //	cout<<A<<" "<<b<<" "<<a<<" "<<B<<endl;
    	return max(h[A]*2+h[b]*2+Abs(sum[A]-sum[b]),h[a]*2+h[B]*2+Abs(sum[a]-sum[B]));
    }
    
    signed main () {
    	scanf("%lld%lld",&n,&m);
    	for (int i=1;i<=n;i++) scanf("%lld",&d[i]),sum[i]=sum[i-1]+d[i-1],d[i+n]=d[i];
    	for (int i=1;i<=n;i++) scanf("%lld",&h[i]),sum[i+n]=sum[i+n-1]+d[i+n-1],h[i+n]=h[i];
    	T.build(1,1,n<<1);
    	while (m--) {
    		int a,b;scanf("%lld%lld",&a,&b);
    		int ans=0;
    		if (a<=b) ans=ask(b+1,a+n-1);
    		else ans=ask(b+1,a-1);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    WCF后续之旅(3): WCF Service Mode Layer 的中枢—Dispatcher
    .Net 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)
    我的WCF之旅(13):创建基于MSMQ的Responsive Service
    .net程序集强名称签名实践
    WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Policy Injection Application Block 的集成
    .Net 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等) 2
    WCF后续之旅(6): 通过WCF Extension实现Context信息的传递
    SilverlightCatchWcfError
    WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成
    WCF后续之旅(4):WCF Extension Point 概览
  • 原文地址:https://www.cnblogs.com/FridayZ/p/13977765.html
Copyright © 2011-2022 走看看