题意:
白板题,略去;
题解:
首先根据操作用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