题目大意:给定n个点,每个点沿数轴匀速直线运动,多次改变某个点的速度和询问当前离数轴最远的点
标解见http://pan.baidu.com/share/link?shareid=4093182173&uk=2587171485#path=%252F%25E9%259B%2586%25E8%25AE%25AD%25E9%2598%259F%25E4%25BA%2592%25E6%25B5%258B%25202015%2520Round%2520%25231%2520%25E9%25A2%2598%25E8%25A7%25A3
我的做法是将时间放在x轴上,坐标放在y轴上,这样操作等价于插入线段和询问某一横坐标上的最大值
然后就是HEOI2013的Segment了。。。
时间复杂度O((n+C)*(logt)^2+Q*logt) 不是很卡啊= = 虽然比标解多了个log
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 700700
#define INF 0x3f3f3f3f3f3f3f3fll
using namespace std;
long long F(long long k,long long b,int x)
{
return k*x+b;
}
long double Get_Intersection(long long k1,long long b1,long long k2,long long b2)
{
return -(long double)(b1-b2)/(k1-k2);
}
struct Segtree{
Segtree *ls,*rs;
long long k,b;
void* operator new (size_t)
{
#define L (1<<16)
static Segtree *mempool,*C;
if(C==mempool)
mempool=(C=new Segtree[L])+L;
C->ls=0x0;
C->rs=0x0;
C->k=0;
C->b=-INF;
return C++;
}
friend void Insert(Segtree *&p,int x,int y,int l,int r,long long k,long long b)
{
int mid=x+y>>1;
if(!p) p=new Segtree;
if(x==l&&y==r)
{
long long fx=F(p->k,p->b,x);
long long fy=F(p->k,p->b,y);
long long _fx=F(k,b,x);
long long _fy=F(k,b,y);
if( fx>=_fx && fy>=_fy )
return ;
if( fx<=_fx && fy<=_fy )
{
p->k=k;
p->b=b;
return ;
}
long double intersection=Get_Intersection(p->k,p->b,k,b);
if(intersection<=mid+0.5)
{
if(fx>_fx)
Insert(p->ls,x,mid,l,mid,p->k,p->b),p->k=k,p->b=b;
else
Insert(p->ls,x,mid,l,mid,k,b);
}
else
{
if(fy>_fy)
Insert(p->rs,mid+1,y,mid+1,r,p->k,p->b),p->k=k,p->b=b;
else
Insert(p->rs,mid+1,y,mid+1,r,k,b);
}
return ;
}
if(r<=mid)
Insert(p->ls,x,mid,l,r,k,b);
else if(l>mid)
Insert(p->rs,mid+1,y,l,r,k,b);
else
Insert(p->ls,x,mid,l,mid,k,b) , Insert(p->rs,mid+1,y,mid+1,r,k,b) ;
}
friend long long Get_Max(Segtree *p,int x,int y,int tim)
{
int mid=x+y>>1;
if(!p) return -INF;
if(x==y)
return F(p->k,p->b,tim);
if(tim<=mid)
return max(F(p->k,p->b,tim),Get_Max(p->ls,x,mid,tim));
else
return max(F(p->k,p->b,tim),Get_Max(p->rs,mid+1,y,tim));
}
}*tree1,*tree2;
struct Query{
int type,tim;//0-modifiction 1-query
long long k,b;
int l,r;
}queries[M];
int n,m;
int last[100100];
int main()
{
int i,x,y;
char p[20];
cin>>n>>m;
for(i=1;i<=n;i++)
{
queries[i].type=0;
queries[i].tim=0;
scanf("%d",&x);
queries[i].k=0;
queries[i].b=x;
queries[i].l=0;
queries[i].r=1000000000;
last[i]=i;
}
for(i=n+1;i<=n+m;i++)
{
scanf("%d%s",&queries[i].tim,p);
if(p[0]=='q')
queries[i].type=1;
else
{
scanf("%d%d",&x,&y);
queries[last[x]].r=queries[i].tim;
queries[i].k=y;
queries[i].b=F(queries[last[x]].k,queries[last[x]].b,queries[i].tim)-(long long)queries[i].tim*y;
queries[i].l=queries[i].tim;
queries[i].r=1000000000;
last[x]=i;
}
}
for(i=1;i<=m+n;i++)
{
if(queries[i].type==0)
{
Insert(tree1,0,1000000000,queries[i].l,queries[i].r,queries[i].k,queries[i].b);
Insert(tree2,0,1000000000,queries[i].l,queries[i].r,-queries[i].k,-queries[i].b);
}
else
{
long long ans1=Get_Max(tree1,0,1000000000,queries[i].tim);
long long ans2=Get_Max(tree2,0,1000000000,queries[i].tim);
printf("%lld\n",max(abs(ans1),abs(ans2)));
}
}
return 0;
}