CF631E Product Sum
前言
不知道为什么题解里的李超线段树都要分两种情况讨论,我觉得的大可不必,其实一遍就好了。
分析
设
对于
对于
将两式化简会发现它们都是
发现好像没有单调性,并且二分的斜率优化我也不会,就去考虑李超线段树。
将与
这里大多题解都用了两次 for 循环,正着反着都做了一遍,其实可以将线段先全部插入,再查询,就可以枚举一次了,详见代码,好像还是两次 for 循环。
#include<bits/stdc++.h> #define N 200005 #define T 2000005 #define int long long #define ls u<<1 #define rs u<<1|1 #define INF 1e13 using namespace std; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } int n,ans1,ans2; int tree[T<<2]; int a[N],sum[N],k[N],b[N]; int calc(int x,int id){return x*k[id]+b[id];} int Query(int u,int l,int r,int x){ if(l==r) return calc(x,tree[u]); int mid=(l+r)>>1,res=calc(x,tree[u]); if(x<=mid) res=max(res,Query(ls,l,mid,x)); else res=max(res,Query(rs,mid+1,r,x)); return res; } void UpDate(int u,int l,int r,int id){ if(!tree[u]) return void(tree[u]=id); if(calc(l,id)>calc(l,tree[u])&&calc(r,id)>calc(r,tree[u])) return void(tree[u]=id); else if(calc(l,id)<=calc(l,tree[u])&&calc(r,id)<=calc(r,tree[u])) return ; int mid=(l+r)>>1; if(k[id]>k[tree[u]]){ if(calc(mid,id)>calc(mid,tree[u])) UpDate(ls,l,mid,tree[u]),tree[u]=id; else UpDate(rs,mid+1,r,id); }else{ if(calc(mid,id)>calc(mid,tree[u])) UpDate(rs,mid+1,r,tree[u]),tree[u]=id; else UpDate(ls,l,mid,id); } } signed main(){ n=read(); for(int i=1;i<=n;++i) a[i]=read(),sum[i]=sum[i-1]+a[i],ans2+=i*a[i]; for(int i=1;i<=n;++i){ k[i]=i,b[i]=-sum[i]; UpDate(1,-1e6,1e6,i); } for(int i=1;i<=n;++i){ int x=Query(1,-1e6,1e6,a[i]); ans1=max(ans1,x-i*a[i]+sum[i]); } printf("%lld\n",ans2+ans1); return 0; }
本文作者:南风未起
本文链接:https://www.cnblogs.com/jiangchen4122/p/16893712.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步