记录编号 244315 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2011]工作评估 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 7.358 s
提交时间 2016-03-31 18:29:46 内存使用 117.86 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=100000+10;
const int size=150;
const int oo=2000000000;
struct node
{
	int first,second;
} block[maxn/size+5][size*size+5],start[maxn/size+5][size+5],end[maxn/size+5][size+5];
int bn[maxn/size+5],sn[maxn/size+5],en[maxn/size+5];
int blockl[maxn/size+5],blockd[maxn/size+5];
int limit[maxn],delta[maxn];
int n,m;

bool cmq(const node &a,const node &b)
{
	return (a.first<b.first || (a.first==b.first && a.second<b.second));
}

void process(node p[],int &n)
{
	sort(p,p+n,cmq);
	int _n=n;n=0;
	for (int i=1;i<_n;i++)
	{
		while (n>=0 && p[i].second>=p[n].second) n--;
		p[++n]=p[i];
	}
	n++;
}	

void prepare()
{
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;i++) scanf("%d",&delta[i]);
	for (int i=0;i<n;i++) scanf("%d",&limit[i]);
	for (int i=0;i*size<n;i++)
	{
		int l=i*size,r=i*size+size-1;
		if (r>=n) r=n-1;
		for (int u=l;u<=r;u++)
		for (int v=u,pl=oo,pd=0;v>=l;v--)
		{
			int nd=pd+delta[v],nl=min(pl,limit[v]+pd);
			node xxx;xxx.first=nl;xxx.second=nd;
			if (nd>pd) block[i][bn[i]++]=xxx;
			if (v==l) start[i][sn[i]++]=xxx;
			if (u==r) end[i][en[i]++]=xxx;
			if (v==l && u==r) blockl[i]=nl,blockd[i]=nd;
			pl=nl;pd=nd;
		}
		process(block[i],bn[i]);
		process(start[i],sn[i]);
		process(end[i],en[i]);
	}

	//printf("%0.9lf\n",(double)clock()/CLOCKS_PER_SEC);
}

int getbest(node p[],int n,int v,int nowbest)
{
	if (nowbest>=v+p[0].second) return nowbest;
	int l=-1,r=n;
	while (l+1<r)
	{
		int mid=((l+r)>>1);
		if (v+p[mid].second>=p[mid].first) l=mid;
		else r=mid;
	}
	int res=v;
	if (l>=0 && l<n) res=max(res,p[l].first);
	if (l+1<n) res=max(res,p[l+1].second+v);
	return res;
}

void work()
{
	for (;m--;)
	{
		int L,R,V,now,res;
		scanf("%d%d%d",&L,&R,&V);res=now=V;
		L--;R--;
		int xxx=0;
		for (int i=L/size;i<=R/size;i++)
		if (i*size>=L && i*size+size-1<=R)
		{
			res=max(res,getbest(block[i],bn[i],V,res));
			res=max(res,getbest(start[i],sn[i],now,res));
			now=max(min(blockl[i],now+blockd[i]),getbest(end[i],en[i],V,-oo));
		} else
		{
			for (int j=max(L,i*size),tmp=now;j<=R && j<i*size+size;j++)
			{
				tmp=max(V,min(tmp+delta[j],limit[j]));
				res=max(res,tmp);
			}
			if (R>i*size+size-1)
			for (int j=min(R,i*size+size-1),pl=oo,pd=0;j>=L && j>=i*size;j--)
			{
				int nd=pd+delta[j],nl=min(pl,limit[j]+pd);
				now=max(now,min(V+nd,nl));
				pl=nl;pd=nd;
			}	
		}
		printf("%d\n",res);
	}
	//printf("%0.9lf\n",(double)clock()/CLOCKS_PER_SEC);
}

int main()   
{
	freopen("nt2011_zej_b.in","r",stdin);
	freopen("nt2011_zej_b.out","w",stdout);
	prepare();
	work();
}