JZOJ-senior-5936. 【NOIP2018模拟10.29】逛公园

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HuangXinyue1017/article/details/83546935

Time Limits: 2000 ms Memory Limits: 524288 KB

Description

策策由于在noip2017考试当天去逛公园了,没能出现在考场上,转眼到了noip2018,策策的公园也悄然转变,策策能否克服诱惑,成功坐在考场上呢?

策策同学特别喜欢逛公园,公园可以看做有n个景点的序列,每个景点会给策策带来di 的愉悦度,策策初始有x0 的愉悦度,然而愉悦度也是有上限的,他在每个景点的愉悦度上限为li ,策策想要从 l 到 r这一段景点中选择一段景点参观(从这一段的左端点逛到这一段的右端点),策策想知道他最终的愉悦度的最大值是多少,你能帮帮他吗?(区间可以为空,也就是说答案最小为x0 )

Input

第一行两个数n,q 表示景点序列长度 和 询问个数
第二行n个数 表示di
第三行n个数 表示li
接下来q行,每行3个数:
表示 l ,r ,x0
下标均从1开始

Output

共q行,每行1个数表示愉悦度的最大值

Sample Input

6 3
0 5 3 2 0 4
8 10 8 1 9 9
1 3 9
2 6 3
3 4 0

Sample Output

10
8
3

样例说明
询问1 初始愉悦度9 只逛第2个公园 9+5=14 大于l2 ans=10
询问2 初始愉悦度3 从2逛到3 3+5+3=11 大于l3 ans=8
询问3 初始愉悦度0 只逛第3个公园 ans=3

Data Constraint

在这里插入图片描述

Solution

  • 50%:
  • 对于每个点,要是走它能使答案更优,那么走,否则就以初始值从下一个点开始走
  • 时间复杂度 O ( q n ) O(q*n)
  • 100%:
  • 定义一些东西:
  • F ( i , j , x 0 ) F(i,j,x_0) 表示以初始值 x 0 x0 经过 l l 到达 r r 后的答案
  • G ( i , j ) = F ( i , j , i n f ) G(i,j)=F(i,j,inf) ( i n f = inf= +∞)
  • S ( i , j ) S(i,j) 表示 i i j j D D 之和
  • 发现两个重要的性质(这题最关键的地方)

  • 1.对于 a > = b a>=b F ( i , j , a ) > = F ( i , j , b ) F(i,j,a)>=F(i,j,b)
  • 2. F ( i , j , x 0 ) = m i n ( G ( i , j ) , x 0 + S ( i , j ) ) F(i,j,x_0)=min(G(i,j),x_0+S(i,j))
  • 推论
  • 对于询问的 l , r l,r ,如果两个子串都在 [ l , r ] [l,r] 中,且 G 1 > = G 2 G1>=G2 S 1 > = S 2 S1>=S2
  • 那么第二个子串是一定不会取到的(由性质二得到)
  • 于是考虑分块
  • 先考虑块内的贡献

  • 每块大小为 n \sqrt{n} ,子串个数就是 O ( n ) O(n)
  • 我们可以先将每一块中子串的 G G S S 预处理出来
  • 根据推论,用单调栈将没用的子串扔掉
  • 那么剩下的序列就是个 G G 不断减小, S S 不断增大的序列
  • 对于每次的询问 x 0 x_0 ,最大的点一定是 m i n min 函数中间的某处
  • m i n min 函数前半部分递减,后半部分递增,看成两条直线,则相交处将有最大值)
  • 二分就可以得到最大的答案啦
  • 再考虑块间的贡献

  • 两种情况:
  • 1.当前块开始,后面某块结束
  • 2.前面某块开始,当前块结束
  • 参考 50% 的暴力策略,用 Y Y 代表上一个块给这一个块带来的贡献,当然是越大越好
  • (每个块中的前缀和后缀可以在处理子串的同时预处理)
  • 利用前缀和 Y Y ,可采用和块内贡献相同的二分方法计算答案
  • 利用后缀,同理也可计算这一块可以提供给下一块的 Y Y
  • 分三种情况讨论
  • 1.从上一个 Y Y 走满整块
  • 2.从某个后缀走到末尾
  • 3.直接取 x 0 x0
  • 三者的最大值就是 Y Y
  • 时间复杂度 O ( n n + q n l o g n ) O(n*\sqrt{n}+q*\sqrt{n}*logn)
  • (code中的 S S G G 的单调性和题解中的相反,本质相同)
  • (结合code中的注释体验++)

Code

#include<algorithm>
#include<cstdio>
#include<cmath>

#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)

using namespace std;

const int N=4e4+5,M=2e2+5,inf=1e9;
int n,q,len,tot;
int a[N],s[N],up[N],be[N];
struct node{int g,s;}d[N],d1[M],d2[M];
node c[M][N],all[M],pre[M][M],suf[M][M];

bool cmp(node x,node y)
{
	return x.g<y.g||x.g==y.g&&x.s>y.s;
}

void get(node *d,int t,node *c)//stack g+ s-
{
	sort(d+1,d+1+t,cmp);
	int tp=0;
	fo(i,1,t) if(d[i].g>d[i-1].g)
	{
		while(tp&&c[tp].s<d[i].s) --tp;
		c[++tp]=d[i];
	}
	c[0].g=tp;
}

void prepare()
{
	fo(k,1,tot)
	{
		int st=(k-1)*len+1,en=min(k*len,n);
		int t=0,t1=0,t2=0;
		fo(i,st,en)
		{
			int now=inf;
			fo(j,i,en)
			{
				now=min(now+a[j],up[j]);
				d[++t]=(node){now,s[j]-s[i-1]};//each
				if(i==st) d1[++t1]=d[t];//prefix
				if(j==en) d2[++t2]=d[t];//suffix
			}
			if(i==st) all[k]=d[t];//a whole block
		}
		get(d,t,c[k]);
		get(d1,t1,pre[k]);
		get(d2,t2,suf[k]);
	}
}

int solve(node *b,int x0)
{
	int l=1,r=b[0].g;
	while(r-l>1)
	{
		int mid=(l+r)>>1;
		if(b[mid].g<x0+b[mid].s) l=mid;
			else r=mid;
	}
	return max(min(b[l].g,x0+b[l].s),min(b[r].g,x0+b[r].s));
}

int main()
{
	freopen("park.in","r",stdin);
	freopen("park.out","w",stdout);
	scanf("%d%d",&n,&q);
	len=sqrt(n),tot=(n-1)/len+1;
	fo(i,1,n) scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
	fo(i,1,n) scanf("%d",&up[i]),be[i]=(i-1)/len+1;
	
	prepare();
	
	while(q--)
	{
		int l,r,x;
		scanf("%d%d%d",&l,&r,&x);
		int st=be[l],en=be[r],ans=x,y=x;
		fo(i,l,min(r,st*len))
		{
			y=max(x,min(y+a[i],up[i]));
			ans=max(ans,y);
		}
		fo(i,st+1,en-1)
		{
			ans=max(ans,solve(c[i],x));//begin and end in block i
			ans=max(ans,solve(pre[i],y));//end in block i
			//update new y
			y=min(all[i].g,y+all[i].s);//1
			y=max(solve(suf[i],x)/*2*/,max(x,y)/*3*/);
		}
		if(st<en)
		{
			fo(i,max(l,(en-1)*len+1),r)
			{
				y=max(x,min(y+a[i],up[i]));
				ans=max(ans,y);
			}
		}
		printf("%d\n",ans);
	}
}

猜你喜欢

转载自blog.csdn.net/HuangXinyue1017/article/details/83546935