题意:支持插入直线,询问某个x坐标下最大的直线对应的y值(x为整数)
首先为整数,意味着可以用维护下标的数据结构维护,其次我们分析发现对于两条直线,至多相交一次,考虑最后的答案一定为类似凸壳的东西,一条线段至多把凸壳分为三段,那么就可以递归到左边和右边去做,O(mlogn)即可。
附数据生成器:
输入:一个m问题数(m<=100000),奇数 y=kx+b,k,b(k,b小于等于100),偶数 x(100000>=x>=1)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib> 6 7 using namespace std; 8 9 int random(int x) 10 { 11 return rand()*rand()%x; 12 } 13 int main() 14 { 15 srand(1); 16 int n=100000,m=100000; 17 printf("%d\n",m); 18 for(int i=1;i<=m;i++) 19 { 20 if(i%2==0) 21 { 22 printf("%d\n",random(n)+1); 23 continue; 24 } 25 int k=random(100)+1,b=random(100)+1; 26 if(random(100)<50)k=-k; 27 if(random(100)<50)b=-b; 28 printf("%d %d\n",k,b); 29 } 30 return 0; 31 }
附对应代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 6 const int maxn=100005; 7 using namespace std; 8 9 struct mydata 10 { 11 int son[2]; 12 int k,b; 13 }; 14 int inf=1e9; 15 struct mytree 16 { 17 int np,rt,n; 18 mydata c[maxn<<1]; 19 void build(int &now,int l,int r) 20 { 21 now=++np; 22 c[now]=(mydata){{0,0},0,-inf}; 23 if(l==r)return; 24 int m=(l+r)/2; 25 build(c[now].son[0],l,m); 26 build(c[now].son[1],m+1,r); 27 } 28 void update(int now,int l,int r,int x,int y,int k,int b) 29 { 30 if(x<=l&&r<=y) 31 { 32 int v1=l*c[now].k+c[now].b; 33 int v2=r*c[now].k+c[now].b; 34 int v3=l*k+b; 35 int v4=r*k+b; 36 if(v1<=v3&&v2<=v4) 37 { 38 c[now].k=k; 39 c[now].b=b; 40 return; 41 } 42 else if(v1>=v3&&v2>=v4)return; 43 } 44 45 int m=(l+r)/2; 46 if(y<=m)update(c[now].son[0],l,m,x,y,k,b); 47 else if(x>=m+1)update(c[now].son[1],m+1,r,x,y,k,b); 48 else 49 { 50 update(c[now].son[0],l,m,x,y,k,b); 51 update(c[now].son[1],m+1,r,x,y,k,b); 52 } 53 } 54 int query(int now,int l,int r,int x) 55 { 56 int tmp=c[now].k*x+c[now].b; 57 if(l==r)return tmp; 58 59 int m=(l+r)/2; 60 if(x<=m)return max(tmp,query(c[now].son[0],l,m,x)); 61 else return max(tmp,query(c[now].son[1],m+1,r,x)); 62 } 63 }c; 64 int main() 65 { 66 int n=100000,m; 67 scanf("%d",&m); 68 c.build(c.rt,1,n); 69 int x,ai,bi; 70 for(int i=1;i<=m;i++) 71 { 72 int tmp=-1e9; 73 if(i%2==0) 74 { 75 scanf("%d",&x); 76 printf("%d\n",c.query(c.rt,1,n,x)); 77 continue; 78 } 79 scanf("%d%d",&ai,&bi); 80 c.update(c.rt,1,n,1,n,ai,bi); 81 } 82 return 0; 83 }
浙公网安备 33010602011771号