题意:
白板题,略去;
题解:
首先根据操作用Splay维护序列;
注意维护之后的序列应该保证是n个的;
然后就有三个数组a[i],p[i],q[i];
令f[i]表示用前面的弹珠撞击第i个弹珠的最大得分;
那么f[i]=max(0,-a[i]*p[j]+q[j]);
(0<j<i)
暂时不考虑0,变形可得q[j]=a[i]*p[j]+f[i];
这显然是一个斜率优化的形式,维护一个上凸壳,在凸壳上二分就好了;
0的情况就是加一个原点进去咯,反正不会被T出凸壳;
二分不太好写,但是似乎二分完了对l,r的答案取个max就好写多了(笑);
时间复杂度O(mlogn+nlogn);
这题分明是两道题!
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #define N 410000 #define which(x) (ch[fa[x]][1]==x) using namespace std; typedef long long ll; int fa[N],ch[N][2],size[N],root,tot,cnt; ll val[N],a[N],x[N],y[N]; int n,m,i,st[N],top; char str[100]; void Pushup(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void Rotate(int x) { int f=fa[x]; bool k=which(x); ch[f][k]=ch[x][!k]; ch[x][!k]=f; ch[fa[f]][which(f)]=x; fa[ch[f][k]]=f; fa[x]=fa[f]; fa[f]=x; size[x]=size[f]; Pushup(f); } void Splay(int x,int g) { while(fa[x]!=g) { int f=fa[x]; if(fa[f]==g) { Rotate(x); break; } if(which(x)^which(f)) Rotate(x); else Rotate(f); Rotate(x); } if(!g) root=x; } int rank(int x,int k) { if(k<=size[ch[x][0]]) return rank(ch[x][0],k); else if(k==size[ch[x][0]]+1) return x; else return rank(ch[x][1],k-size[ch[x][0]]-1); } void Insert(int k,ll v) { int x=rank(root,k),y=rank(root,k+1); Splay(x,0),Splay(y,x); fa[++tot]=y; size[tot]=1; ch[y][0]=tot; val[tot]=v; Pushup(y); Pushup(x); } void Change(int k,ll v) { int x=rank(root,k); val[x]=v; Pushup(x); } void Print(int x) { if(!x) return ; Print(ch[x][0]); a[++cnt]=val[x]; Print(ch[x][1]); } double slope(int a,int b) { if(b>=i) return 0; return(double(y[a]-y[b]))/(x[a]-x[b]); } int main() { int j,k,l,r,mid; ll v; scanf("%d%d",&n,&m); tot=2; ch[1][1]=2,fa[2]=1; root=1; for(i=1;i<=m;i++) { scanf("%s%d%lld",str,&k,&v); if(str[0]=='I') Insert(k+1,v); else Change(k+2,v); } cnt=-1; Print(root); for(i=1;i<=n;i++) scanf("%lld%lld",x+i,y+i); st[top=2]=1; for(i=2;i<=n;i++) { l=1,r=top; while(l<=r) { mid=l+r>>1; if(slope(st[mid],st[mid+1])>a[i]) l=mid+1; else r=mid-1; } printf("%lld\n",max(y[st[l]]-a[i]*x[st[l]],y[st[r]]-a[i]*x[st[r]])); while(top>1&&(y[st[top]]-y[st[top-1]])*(x[i]-x[st[top]])<= (y[i]-y[st[top]])*(x[st[top]]-x[st[top-1]])) top--; st[++top]=i; } return 0; }
原文地址:http://blog.csdn.net/ww140142/article/details/47446429