ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1172F Nauuo and Bug 题解

2022-07-13 22:34:32  阅读:119  来源: 互联网

标签:次数 int 题解 sum mid Nauuo lson 减去 Bug


首先将问题转化为执行 sum(A,l,r,p) 后减去了多少次 \(p\)。

注意到若 \(x>y\),则 \(result\) 的初值为 \(x\) 时执行 sum(A,l,r,p) 中减去 \(p\) 的次数不少于 \(result\) 的初值为 \(y\) 时执行 sum(A,l,r,p) 中减去 \(p\) 的次数,故考虑建线段树并对区间 \([l,r]\) 维护 \(c_x\) 表示执行 sum(A,l,r,p) 后恰好减少了 \(x\) 次 \(p\),\(result\) 的最小值。

考虑如何 pushup,一种想法是枚举左儿子减去了 \(x\) 次 \(p\),右儿子减去了 \(y\) 次 \(p\) 进行合并,即若 \(c_{lson,x+1}-1+sum_{lson}-xp\ge c_{rson,y}\),则 \(c_{k,x+y}\) 对 \(\max(c_{lson,x},c_{rson,y}-sum_{lson}+xp)\) 取 \(\min\)。

考虑如何优化,注意到 \(c\) 是随下标增加而不降的,故 \(c_{lson,x+1}\ge c_{lson,x}\),又因为 \(c_{lson,x+1}\ge c_{rson,y}-sum_{lson}+xp\),所以 \(c_{lson,x+1}\ge\max(c_{lson,x},c_{rson,y}-sum_{lson}+xp)\),因而 \(\max(c_{lson,x+1},c_{rson,y-1}-sum_{lson}+(x+1)p)\ge\max(c_{lson,x},c_{rson,y}-sum_{lson}+xp)\)。因此对于每个 \(c_{k,x+y}\) 只需在 \(x\) 最小时更新即可。

我们下面证明上述不等式的左侧也是随下标增加而不降的,即证 \(c_{x+1}-c_{x}\ge p\)。

记 \(b_i\) 表示 \(result\) 的初值为 \(c_x\),对于序列 \(a_{1,..,n}\) 执行 sum(a,1,n,p) 时,第 \(9\) 行的 for 执行完第 \(i\) 次后 result 的值。记 \(d_i\) 表示 \(result\) 的初值为 \(c_x+p-1\),对于序列 \(a_{1,..,n}\) 执行 sum(a,1,n,p) 时,第 \(9\) 行的 for 执行完第 \(i\) 次后 result 的值。原命题等价于证明 \(b\) 中减去 \(p\) 的次数等于 \(c\) 中减去 \(p\) 的次数。

称一个位置是好的,当且仅当 \(result\) 在该位置上减去了 \(p\),可以发现 \(b\) 中至少有一个好的位置的值为 \(0\),否则将 \(c_x\) 减 \(1\) 后减去 \(p\) 的次数仍然是 \(x\) 次,与 \(c_x\) 的定义不符。

找到第一个位置使得该位置在 \(b\) 中不是好的且在 \(d\) 中是好的,在此之前 \(d\) 中数都比 \(b\) 中对应位置的数大 \(p-1\),接下来的一段 \(d\) 中数都比 \(b\) 中对应位置的数小 \(1\),于是可以找到该位置后的第一个位置使得该位置在 \(b\) 中是好的且在 \(d\) 中不是好的,接下来的一段 \(d\) 中数又都比 \(b\) 中对应位置的数大 \(p-1\)……

于是我们发现,\(d\) 中的数要么比 \(b\) 中对应位置的数大 \(p-1\),要么小 \(1\)。更进一步,设最后一个好的 \(0\) 的位置是 \(t\),则 \(d_{t-1}=b_{t-1}+p-1\) 或 \(d_{t-1}=b_{t-1}-1\),由于最后一个好的 \(0\) 在 \(b\) 中是由 \(p\) 减 \(p\) 得来的,故 \(b_{t-1}+a_t=p\),故 \(d_{t-1}+a_t=p-1\) 或 \(d_{t-1}+a_t=2p-1\),而这两种情况都能推出 \(d_t=p-1\),也就是说在 \(t\) 及之前 \(b\) 和 \(d\) 中的数减去 \(p\) 的次数是一样的。

将 \(c_x\) 减 \(1\) 后类似之前可推出新的由 \(result\) 组成的序列 \(b'\) 满足 \(\forall 1\le i\le n\),有 \(b'_i=b_i-1\) 或 \(b'_i=b_i+p-1\), 由 \(b_{t-1}+a_t=p\) 可得 \(b'_{t-1}+a_t=p-1\) 或 \(b'_{t-1}+a_t=2p-1\),而这两种情况也都能推出 \(b'_t=p-1\)。

由 \(c_x\) 的定义知 \(b'\) 中的数减去 \(p\) 的次数比 \(d\) 中的数减去 \(p\) 的次数少 \(1\),而我们又知道 \(b'\) 中的数在 \(t\) 及之前减去 \(p\) 的次数比 \(d\) 中的数在 \(t\) 及之前减去 \(p\) 的次数少 \(1\),故 \(b'\) 和 \(b\) 在 \(t\) 之后减去 \(p\) 的次数相等。又由于 \(b'\) 和 \(d\) 在 \(t\) 之后减去 \(p\) 的次数也相等,故 \(b\) 和 \(d\) 在 \(t\) 之后减去 \(p\) 的次数也相等。

因此,\(b\) 和 \(d\) 中的数减去 \(p\) 的次数是一样的,原命题得证。

由上述结论可知 pushup 更新 \(c\) 可用双指针将复杂度降低至 \(O(r-l+1)\),之后查询在线段树上的 \(\log n\) 个节点上二分出减去 \(p\) 的次数,即可以 \(O(\log^2n)\) 的时间复杂度回答单词询问。故总时间复杂度 \(O(n\log n+m\log^2n)\)。

Code

#include<bits/stdc++.h>
#define LL long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
int n,m;
LL p;
int a[1000002];
LL pre[1000002];
inline int lson(int x)
{
	return (x<<1);
}
inline int rson(int x)
{
	return ((x<<1)|1);
}
struct SegTree
{
	vector<LL> c[4000002];
	inline void build(int k,int l,int r)
	{
		if(l==r)return (void)(c[k].push_back(-inf),c[k].push_back(p-a[l]));
		int mid=((l+r)>>1),ls=lson(k),rs=rson(k);
		build(ls,l,mid),build(rs,mid+1,r);
		for(int i=0;i+1<c[ls].size()+c[rs].size();++i)c[k].push_back(i? inf:-inf);
		for(int i=0,j=0;i<c[ls].size();--j,++i)for(;j<c[rs].size() && (i+1==c[ls].size() || c[ls][i+1]-1+pre[mid]-pre[l-1]-p*i>=c[rs][j]);++j)c[k][i+j]=min(c[k][i+j],max(c[ls][i],c[rs][j]-pre[mid]+pre[l-1]+p*i));
	}
	inline int query(int k,int l,int r,int l1,int r1,LL d)
	{
		if(l>=l1 && r<=r1)
		{
			int L=0,R=c[k].size()-1,Mid;
			for(;L<=R;)
			{
				Mid=((L+R)>>1);
				if(c[k][Mid]<=d)L=Mid+1;
				else R=Mid-1;
			}
			return R;
		}
		int mid=((l+r)>>1),ls=lson(k),rs=rson(k),res;
		if(r1<=mid)return query(ls,l,mid,l1,r1,d);
		if(l1>mid)return query(rs,mid+1,r,l1,r1,d);
		return res=query(ls,l,mid,l1,mid,d),res+query(rs,mid+1,r,mid+1,r1,d+pre[mid]-pre[l1-1]-p*res);
	}
}S;
int main()
{
	scanf("%d%d%lld",&n,&m,&p);
	for(int i=1;i<=n;++i)scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i];
	S.build(1,1,n);
	for(int x,y;m--;)scanf("%d%d",&x,&y),printf("%lld\n",pre[y]-pre[x-1]-p*S.query(1,1,n,x,y,0));
	return 0;
}

标签:次数,int,题解,sum,mid,Nauuo,lson,减去,Bug
来源: https://www.cnblogs.com/18Michael/p/16475832.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有