题目大意:给定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; }
原文地址:http://blog.csdn.net/popoqqq/article/details/44923083