水题写一年系列。
每个机器人的位置随时间的函数应该是个分段函数,每一段都是一次函数。
我们可以离线,把时间离散化掉,就是维护若干线段的最值。
可以先都插进去,然后最后处理询问。
可以用李超线段树来解决。分别维护最大最小值。
复杂度 O(nlog2n)
#include
#include
#include
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int nn,n,lst[N],Q[N*5],aa[N*6],m,n1,n2,now[N];
char s[N];
struct Line{
ll k,b;
ll f(ll x){return k*x+b;}
}a[N*3];
struct oper{
int tim,x,k;
}O[N];
struct node{
int x,y;
}tr[N*6*4];
inline void ins(int p,int l,int r,int x,int y,int id){//最大值
if(x<=l&&r<=y){
if(!tr[p].x){tr[p].x=id;return;}
ll fl=a[tr[p].x].f(aa[l])-a[id].f(aa[l]),fr=a[tr[p].x].f(aa[r])-a[id].f(aa[r]);
if(fl>=0&&fr>=0) return;
if(fl<0&&fr<0){tr[p].x=id;return;}int mid=l+r>>1;
if(fl>0){
if(a[tr[p].x].f(aa[mid])>a[id].f(aa[mid])) ins(p<<1|1,mid+1,r,x,y,id);
else ins(p<<1,l,mid,x,y,tr[p].x),tr[p].x=id;
}else{
if(a[tr[p].x].f(aa[mid])>a[id].f(aa[mid])) ins(p<<1,l,mid,x,y,id);
else ins(p<<1|1,mid+1,r,x,y,tr[p].x),tr[p].x=id;
}return;
}int mid=l+r>>1;
if(x<=mid) ins(p<<1,l,mid,x,y,id);
if(y>mid) ins(p<<1|1,mid+1,r,x,y,id);
}
inline void ins1(int p,int l,int r,int x,int y,int id){//最小值
if(x<=l&&r<=y){
if(!tr[p].y){tr[p].y=id;return;}
ll fl=a[tr[p].y].f(aa[l])-a[id].f(aa[l]),fr=a[tr[p].y].f(aa[r])-a[id].f(aa[r]);
if(fl<=0&&fr<=0) return;
if(fl>0&&fr>0){tr[p].y=id;return;}int mid=l+r>>1;
if(fl>0){
if(a[tr[p].y].f(aa[mid])1,l,mid,x,y,id);
else ins1(p<<1|1,mid+1,r,x,y,tr[p].y),tr[p].y=id;
}else{
if(a[tr[p].y].f(aa[mid])1|1,mid+1,r,x,y,id);
else ins1(p<<1,l,mid,x,y,tr[p].y),tr[p].y=id;
}return;
}int mid=l+r>>1;
if(x<=mid) ins1(p<<1,l,mid,x,y,id);
if(y>mid) ins1(p<<1|1,mid+1,r,x,y,id);
}
inline ll askmn(int p,int l,int r,int x){
if(l==r) return a[tr[p].y].f(aa[x]);
int mid=l+r>>1;
if(x<=mid) return min(askmn(p<<1,l,mid,x),a[tr[p].y].f(aa[x]));
return min(askmn(p<<1|1,mid+1,r,x),a[tr[p].y].f(aa[x]));
}
inline ll askmx(int p,int l,int r,int x){
if(l==r) return a[tr[p].x].f(aa[x]);
int mid=l+r>>1;
if(x<=mid) return max(askmx(p<<1,l,mid,x),a[tr[p].x].f(aa[x]));
return max(askmx(p<<1|1,mid+1,r,x),a[tr[p].x].f(aa[x]));
}
int main(){
// freopen("a.in","r",stdin);
nn=read();m=read();
for(int i=1;i<=nn;++i) a[i].b=read(),now[i]=i;
for(int i=1;i<=m;++i){
aa[i]=read();scanf("%s",s+1);
if(s[1]=='c') O[++n1].tim=aa[i],O[n1].x=read(),O[n1].k=read();
else Q[++n2]=aa[i];
}aa[++m]=0;sort(aa+1,aa+m+1);n=unique(aa+1,aa+m+1)-aa-1;m=nn;
for(int i=1;i<=n1;++i){
int x=O[i].x,l=lower_bound(aa+1,aa+n+1,lst[x])-aa,r=lower_bound(aa+1,aa+n+1,O[i].tim)-aa;
ins(1,1,n,l,r,now[x]);ins1(1,1,n,l,r,now[x]);
a[++m].k=O[i].k;a[m].b=a[now[x]].b+O[i].tim*(a[now[x]].k-a[m].k);
now[x]=m;lst[x]=O[i].tim;
}for(int i=1;i<=nn;++i){
int l=lower_bound(aa+1,aa+n+1,lst[i])-aa;
ins(1,1,n,l,n,now[i]);ins1(1,1,n,l,n,now[i]);
}for(int i=1;i<=n2;++i){
int x=lower_bound(aa+1,aa+n+1,Q[i])-aa;
ll ans=max(-askmn(1,1,n,x),askmx(1,1,n,x));
printf("%lld\n",ans);
}return 0;
}