本文主要是介绍CF1136E Nastya Hasn‘t Written a Legend,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
R e s u l t Result Result
H y p e r l i n k Hyperlink Hyperlink
https://www.luogu.com.cn/problem/CF1136E
D e s c r i p t i o n Description Description
给定一个长度为 n n n的数组 a a a和长度为 n − 1 n-1 n−1的数组 k k k, m m m次询问
包含两种操作
- a x + = y a_x+=y ax+=y,同时若加完之后 a i + 1 < a i + a k a_{i+1}<a_i+a_k ai+1<ai+ak,则令 a i + 1 = a i + a k a_{i+1}=a_i+a_k ai+1=ai+ak,同时继续判断 a i + 2 < 更 新 后 的 a i + 1 + a k + 1 a_{i+2}<更新后的a_{i+1}+a_{k+1} ai+2<更新后的ai+1+ak+1,然后赋值 a i + 2 = 更 新 后 的 a i + 1 + a k + 1 a_{i+2}=更新后的a_{i+1}+a_{k+1} ai+2=更新后的ai+1+ak+1,以此类推,直到不合法为止
- 查询 a [ x ∼ y ] a[x\sim y] a[x∼y]的和
数据范围: n , m ≤ 1 0 5 , ∣ a i ∣ , ∣ k i ∣ ≤ 1 0 9 n,m\leq 10^5,|a_i|,|k_i|\leq 10^9 n,m≤105,∣ai∣,∣ki∣≤109
S o l u t i o n Solution Solution
考虑什么时候满足题目所述条件
a i ≥ a i − 1 + k i − 1 ≥ a i − 2 + k i − 2 + k i − 1 ≥ a j + ∑ l = j i − 1 k l ∣ j < i a_i\geq a_{i-1}+k_{i-1}\geq a_{i-2}+k_{i-2}+k_{i-1}\geq a_j+\sum _{l=j}^{i-1} k_l\ |\ j<i ai≥ai−1+ki−1≥ai−2+ki−2+ki−1≥aj+∑l=ji−1kl ∣ j<i
令 g i = ∑ j = 1 i k i g_i=\sum_{j=1}^i k_i gi=∑j=1iki
则 a i ≥ a 1 + g i − 1 a_i\geq a_1+g_{i-1} ai≥a1+gi−1,貌似有用,但因为 k i k_i ki可以是负数,所以不是很有用
但我们可以让 u i = a i − g i − 1 u_i=a_i-g_{i-1} ui=ai−gi−1
由 a i ≥ a i − 1 + k i − 1 a_i\geq a_{i-1}+k_{i-1} ai≥ai−1+ki−1得
a i − g i − 1 ≥ a i − 1 − g i − 2 + k i − 1 a_{i}-g_{i-1}\geq a_{i-1}-g_{i-2}+k_{i-1} ai−gi−1≥ai−1−gi−2+ki−1
则
u i ≥ u i − 1 u_i\geq u_{i-1} ui≥ui−1
即 u i u_i ui单调不降,所以我们可以用线段树维护一个 u i u_i ui
对于修改操作,只需二分一个断点,然后区间赋值
对于查询操作,只需要查询区间 u i u_i ui的和,然后补上多减的 g g g,后者可以预处理 g g g的前缀和实现
时间复杂度: O ( n log n ) O(n\log n) O(nlogn)
C o d e Code Code
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define N 100010
using namespace std;int n,m;
LL a[N],k[N],g[N],x,y,s[N];
char op[10];
struct xds
{#define lson k<<1#define rson k<<1|1#define mid (l+r>>1)#define gol lson,l,mid#define gor rson,mid+1,rLL dat[N<<2],lzy[N<<2];inline void build(int k=1,int l=1,int r=n){lzy[k]=-9e18;if(l==r) return (void)(dat[k]=a[l]-g[l-1]);build(gol);build(gor);return (void)(dat[k]=dat[lson]+dat[rson]);}inline void reset(int k,int l,int r,LL x){return (void)(lzy[k]=x,dat[k]=(r-l+1)*x);}inline void pushdown(int k,int l,int r){if(lzy[k]!=-9e18) reset(gol,lzy[k]),reset(gor,lzy[k]),lzy[k]=-9e18;return;}inline LL Query(int ql,int qr,int k=1,int l=1,int r=n){if(l>qr||r<ql) return 0;if(ql<=l&&qr>=r) return dat[k];pushdown(k,l,r);return Query(ql,qr,gol)+Query(ql,qr,gor);}inline void Modify(int ql,int qr,LL x,int k=1,int l=1,int r=n){if(l>qr||r<ql) return;if(ql<=l&&qr>=r) return (void)(reset(k,l,r,x));pushdown(k,l,r);Modify(ql,qr,x,gol);Modify(ql,qr,x,gor);return (void)(dat[k]=dat[lson]+dat[rson]);}#undef lson#undef rson#undef mid#undef gol#undef gor
}T;
inline LL read()
{char c;LL d=1,f=0;while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;return d*f;
}
signed main()
{n=read();for(register int i=1;i<=n;i++) a[i]=read();for(register int i=1;i<n;i++) g[i]=g[i-1]+read(),s[i]=s[i-1]+g[i];T.build();m=read();while(m--){scanf("%s",op);x=read();y=read();if(op[0]=='s') printf("%lld\n",T.Query(x,y)+s[max(0ll,y-1)]-s[max(0ll,x-2)]);else{int l=x,r=n,mid;LL v=T.Query(x,x)+y;while(l<=r){int mid=l+r>>1;LL k=T.Query(mid,mid);if(k==v) break;if(k>v) r=mid-1;else l=mid+1;}T.Modify(x,l+r>>1,v);}}
}
这篇关于CF1136E Nastya Hasn‘t Written a Legend的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!