[codeforces455E]Function
来源:互联网 发布:linux cp命令略过目录 编辑:程序博客网 时间:2024/06/09 20:49
题面
Serega and Fedor play with functions. One day they came across a very interesting function. It looks like that:
f(1, j) = a[j], 1 ≤ j ≤ n.
f(i, j) = min(f(i - 1, j), f(i - 1, j - 1)) + a[j], 2 ≤ i ≤ n, i ≤ j ≤ n.
Here a is an integer array of length n.
有m个询问,每次给出x,y,求f(x,y)
1≤n,m≤100000 1≤x≤y≤100000
分析
f(x,y)可以看成是从某个(1,i)出发的路径。其中i∈[y-x+1,y]
为了使答案最优,路径一定是一段(i,j)—>(i+1,j),再是一段(i,j)—>(i+1,j+1)
那么考虑i对f(x,y)的贡献,它等于:
i比j更优,当且仅当满足:
整理得到:
发现i,j可以表示成ax+b的形式。
那么可以把询问区间像线段树那样分成log块,然后每一块分别求一次答案。用线段树维护区间里直线的最优值即可。
维护的方法:线段树的每个节点存一个线段。如果新加入一条线段,在这个节点和当前已有线段交叉,那么把在当前区间中占优部分更多的保留,另一个根据相交情况,下传到左区间或右区间。
时间复杂度
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define min(a,b) ((a)<(b)?(a):(b))using namespace std;const int N=100005,M=262250;typedef long long LL;int n,m,a[N],sum[N],now,T[M],Y1[M],Y2[M],A[N],B[N],visit[M],X[N],Y[N],Ans[N];vector <int> h[M];char c,S[12];int read(){ for (c=getchar();c<'0' || c>'9';c=getchar()); int x=c-48; for (c=getchar();c>='0' && c<='9';c=getchar()) x=x*10+c-48; return x;}void Add(int l,int r,int a,int b,int v,int x){ if (l==a && r==b) { h[x].push_back(v); return; } int mid=l+r>>1; if (b<=mid) Add(l,mid,a,b,v,x<<1);else if (a>mid) Add(mid+1,r,a,b,v,x<<1|1);else { Add(l,mid,a,mid,v,x<<1); Add(mid+1,r,mid+1,b,v,x<<1|1); }}void Ins(int l,int r,int v,int x){ if (visit[x]!=now) { visit[x]=now; if (l==r) T[x]=A[v]*l+B[v];else { T[x]=v; Y1[x]=A[v]*l+B[v]; Y2[x]=A[v]*r+B[v]; } return; } if (l==r) { T[x]=min(T[x],A[v]*l+B[v]); return; } int y1=A[v]*l+B[v],y2=A[v]*r+B[v]; if (y1>=Y1[x] && y2>=Y2[x]) return; if (y1<=Y1[x] && y2<=Y2[x]) { Y1[x]=y1; Y2[x]=y2; T[x]=v; return; } int mid=l+r>>1; if (A[v]*mid+B[v]>A[T[x]]*mid+B[T[x]]) { if (y1<Y1[x]) Ins(l,mid,v,x<<1);else Ins(mid+1,r,v,x<<1|1); }else { if (y1<Y1[x]) Ins(mid+1,r,T[x],x<<1|1);else Ins(l,mid,T[x],x<<1); T[x]=v; Y1[x]=y1; Y2[x]=y2; }}void query(int l,int r,int v,int id,int x){ if (visit[x]!=now) return; if (l==r) { Ans[id]=min(Ans[id],T[x]); return; } int mid=l+r>>1; if (v<=mid) query(l,mid,v,id,x<<1);else query(mid+1,r,v,id,x<<1|1); Ans[id]=min(Ans[id],A[T[x]]*v+B[T[x]]);}void solve(int l,int r,int x){ if (l<r) { int mid=l+r>>1; solve(l,mid,x<<1); solve(mid+1,r,x<<1|1); } if (h[x].empty()) return; now=x; for (int i=l;i<=r;i++) Ins(0,n,i,1); vector <int> ::iterator it; for (it=h[x].begin();it!=h[x].end();it++) query(0,n,Y[*it]-X[*it],*it,1);}void write(int x){ if (x==0) { putchar('0'); putchar('\n');return; } int len=0; for (;x>0;x/=10) S[len++]=x%10; for (int i=len-1;i>=0;i--) putchar(S[i]+'0'); putchar('\n');}int main(){ n=read(); for (int i=1;i<=n;i++) { a[i]=read(); sum[i]=sum[i-1]+a[i]; A[i]=-a[i]; B[i]=i*a[i]-sum[i]; } m=read(); for (int i=0;i<m;i++) { X[i]=read(); Y[i]=read(); Ans[i]=-1e9; Add(1,n,Y[i]-X[i]+1,Y[i],i,1); } memset(Y1,127,sizeof(Y1)); memset(Y2,127,sizeof(Y2)); memset(Ans,127,sizeof(Ans)); solve(1,n,1); for (int i=0;i<m;i++) write(Ans[i]+sum[Y[i]]); return 0;}
- [codeforces455E]Function
- Function
- function
- function
- function $()
- Function
- function
- Function
- $(function(){...});
- function
- Function
- function
- Function
- function
- (function(){})()
- $(function)
- $(function(){...});
- $(function(){});
- 你连Bug都抓不住,还谈什么参与感?
- 指纹识别-传感器原理
- java计算机网络
- arcgis catalog 连接sde时出现 Target state not found in the STATES table 错误
- html页面转换成pdf插件 jspdf
- [codeforces455E]Function
- ContentProvider
- 一个txt的自我告白
- 表单序列化,获取Json对象
- 【Linux学习笔记】六、压缩解压命令
- HDU
- 配置mac版sublime text lua编译环境
- 检索blob,clob对象效率很慢。。
- React browserHistory.push时如何优雅地传参