# 凸包（壳）算法小结

$y_{i}-k*x_{i}+q_{i}-k*p_{i}>=0$

  1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 #define N 30010
6 #define db double
8 db x[N],y[N],p[N],q[N];
9 struct edge{int zhong,next;}s[N<<1];
10 inline void add(int qi,int zhong)
12 int deep[N],son[N],size[N],fa[N],dfn[N],num,top[N],anti[N];
13 inline void dfs1(int rt,int Vater)
14 {
15     fa[rt]=Vater;deep[rt]=deep[Vater]+1,size[rt]=1;
16     register int i,u;
18         if((u=s[i].zhong)!=Vater)
19         {
20             dfs1(u,rt),size[rt]+=size[u];
21             if(size[u]>size[son[rt]])son[rt]=u;
22         }
23 }
24 inline void dfs2(int rt,int tp)
25 {
26     dfn[rt]=++num,top[rt]=tp;anti[num]=rt;
27     if(son[rt])dfs2(son[rt],tp);
28     register int i,u;
30         if((u=s[i].zhong)!=fa[rt]&&u!=son[rt])dfs2(u,u);
31 }
32 struct pt
33 {
34     db x,y;pt(db a=0,db b=0){x=a,y=b;}
35     inline pt operator + (const pt &b) const {return pt(x+b.x,y+b.y);}
36     inline pt operator - (const pt &b) const {return pt(x-b.x,y-b.y);}
37     inline db operator * (const pt &b) const {return x*b.y-y*b.x;}
39 struct node
40 {
41     node *ch[2];
42     pt *xy,*pq;
43     int lxy,lpq;
44 }*root,mem[N<<1];int tot;
45 inline bool mt1(const pt &a,const pt &b){return a.x==b.x?a.y<b.y:a.x<b.x;}
46 #define inf 0x7fffffff
47 inline double max(db a,db b){return a>b?a:b;}
48 inline int solve(pt *x,int len)
49 {
50     sort(x,x+len,mt1);
51     register int i,top=-1;
52     for(i=0;i<len;++i)
53     {
54         while(top>0&&(sta[top]-sta[top-1])*(x[i]-sta[top])>=0)--top;
55         sta[++top]=x[i];
56     }
57     for(i=0;i<=top;++i)x[i]=sta[i];
59 }
60 inline db query(pt *x,db k,int len)
61 {
62     if(len==0)return x[0].y-k*x[0].x;
63     int l=0,r=len-1,mi,ans=0;
64     pt q=pt(1,k),tmp;
65     while(l<=r)
66     {
67         mi=(l+r)>>1,tmp=x[mi+1]-x[mi];
68         if(tmp*q>=0)ans=mi,r=mi-1;
69         else l=mi+1;
70     }
71     return max(x[ans].y-k*x[ans].x,x[ans+1].y-k*x[ans+1].x);
72 }
73 inline node* build(int l,int r)
74 {
75     node *o=mem+(tot++);
78     for(int i=l;i<=r;++i)
79         o->xy[i-l]=pt(x[anti[i]],y[anti[i]]),o->pq[i-l]=pt(p[anti[i]],q[anti[i]]);
80     o->lxy=solve(o->xy,r-l+1),o->lpq=solve(o->pq,r-l+1);
81     if(l==r)return o;
82     register int mi=(l+r)>>1;
83     o->ch[0]=build(l,mi),o->ch[1]=build(mi+1,r);
84     return o;
85 }
86 inline double qxy(node *o,int l,int r,int L,int R,db k)
87 {
88     if(L<=l&&r<=R)return query(o->xy,k,o->lxy);
89     register int mi=(l+r)>>1;
90     db ret=-inf;
91     if(L<=mi)ret=qxy(o->ch[0],l,mi,L,R,k);
92     if(mi<R)ret=max(ret,qxy(o->ch[1],mi+1,r,L,R,k));
93     return ret;
94 }
95 inline double qpq(node *o,int l,int r,int L,int R,db k)
96 {
97     if(L<=l&&r<=R)return query(o->pq,k,o->lpq);
98     register int mi=(l+r)>>1;
99     db ret=-inf;
100     if(L<=mi)ret=qpq(o->ch[0],l,mi,L,R,k);
101     if(mi<R)ret=max(ret,qpq(o->ch[1],mi+1,r,L,R,k));
102     return ret;
103 }
104 #define eps 1e-5
105 inline db queryxy(int a,int b,db k)
106 {
107     db ret=-inf;
108     while(top[a]^top[b])
109     {
110         if(deep[top[a]]<deep[top[b]])a^=b,b^=a,a^=b;
111         ret=max(ret,qxy(root,1,n,dfn[top[a]],dfn[a],k)),a=fa[top[a]];
112     }
113     if(deep[a]<deep[b])a^=b,b^=a,a^=b;
114     return max(ret,qxy(root,1,n,dfn[b],dfn[a],k));
115 }
116 inline db querypq(int a,int b,db k)
117 {
118     db ret=-inf;
119     while(top[a]^top[b])
120     {
121         if(deep[top[a]]<deep[top[b]])a^=b,b^=a,a^=b;
122         ret=max(ret,qpq(root,1,n,dfn[top[a]],dfn[a],k)),a=fa[top[a]];
123     }
124     if(deep[a]<deep[b])a^=b,b^=a,a^=b;
125     return max(ret,qpq(root,1,n,dfn[b],dfn[a],k));
126 }
127 int main()
128 {
129 //    freopen("Ark.in","r",stdin);
130     register int i,m,a,b;scanf("%d",&n);
131     for(i=1;i<=n;++i)scanf("%lf",&x[i]);
132     for(i=1;i<=n;++i)scanf("%lf",&y[i]);
133     for(i=1;i<=n;++i)scanf("%lf",&p[i]);
134     for(i=1;i<=n;++i)scanf("%lf",&q[i]);
136     dfs1(1,0),dfs2(1,1),root=build(1,n);
137     db l,r,mi,ans;scanf("%d",&m);
138     while(m--)
139     {
140         scanf("%d%d",&a,&b);
141         l=0,r=1e5,ans=0;
142         while(r-l>eps)
143         {
144             mi=(l+r)/2;
145             if(queryxy(a,b,mi)+querypq(a,b,mi)>=0)l=mi,ans=mi;
146             else r=mi;
147         }
148         printf("%.4lf\n",ans);
149     }
150 }
bzoj2402

  1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4 using namespace std;
5 #define LL long long
6 #define L 350
7 #define N 100010
8 #define INF 0x3fffffffffffffffll
9 int belong[N],n,len,num[L],sta[L][L];
10 //#define int long long
11 LL a[N],a0[L],d[L],upg[L];
12 char B[1<<15],*S=B,*T=B;
13 #define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
14 inline int read()
15 {
16     int x=0,f=1;register char c=getc;
17     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getc;}
18     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
19     return x*f;
20 }
21 inline LL max(LL a,LL b){return a>b?a:b;}
22 inline int min(int a,int b){return a<b?a:b;}
23 inline LL calc(int id)
24 {
25     if(id==0)return -INF;
26     return a[id]+a0[belong[id]]+d[belong[id]]*(id-len*(belong[id]-1)-1)+upg[belong[id]];
27 }
28 inline void clear(int id)
29 {
30     for(int i=len*(id-1)+1;i<=min(n,len*id);++i)a[i]=calc(i);
31     a0[id]=d[id]=upg[id]=0;
32 }
33 inline LL chaji(LL a,LL b,LL c,LL d){return a*d-b*c;}
34 inline void build(int id)
35 {
36     register int i,top=0;
37     for(i=len*(id-1)+1;i<=min(n,len*id);++i)
38     {
39         while(top>1&&chaji(sta[id][top]-sta[id][top-1],calc(sta[id][top])-calc(sta[id][top-1]),i-sta[id][top],calc(i)-calc(sta[id][top]))>=0)--top;
40         sta[id][++top]=i;
41     }
42     num[id]=top;
43 }
44 inline LL query(int id)
45 {
46     int l=2,r=num[id],mi,ans=1;
47     while(l<=r)
48     {
49         mi=l+r>>1;
50         if(calc(sta[id][mi-1])<=calc(sta[id][mi]))
51             ans=mi,l=mi+1;
52         else r=mi-1;
53     }
54     return calc(sta[id][ans]);
55 }
56 inline void update(int l,int r,int val)
57 {
58     int ida=belong[l],idb=belong[r],i;
59     LL tmpa0=0;
60     if(ida==idb)
61     {
62         clear(ida);
63         for(i=l;i<=r;++i)tmpa0+=val,a[i]+=tmpa0;
64         build(ida);
65         return;
66     }
67     clear(ida);
68     for(i=l;i<=len*ida;++i)tmpa0+=val,a[i]+=tmpa0;
69     build(ida);
70     for(i=ida+1;i<idb;++i)a0[i]+=tmpa0+val,d[i]+=val,tmpa0+=(LL)len*val;
71     clear(idb);
72     for(i=len*(idb-1)+1;i<=r;++i)tmpa0+=val,a[i]+=tmpa0;
73     for(i=r+1;i<=min(n,len*idb);++i)a[i]+=tmpa0;
74     build(idb);
75     for(i=idb+1;i<=belong[n];++i)upg[i]+=tmpa0;
76 }
77 inline LL query(int l,int r)
78 {
79     LL ret=-INF;
80     int ida=belong[l],idb=belong[r],i;
81     if(ida==idb)
82     {
83         for(i=l;i<=r;++i)ret=max(ret,calc(i));
84         return ret;
85     }
86     for(i=l;i<=len*ida;++i)ret=max(ret,calc(i));
87     for(i=ida+1;i<idb;++i)ret=max(ret,query(i));
88     for(i=len*(idb-1)+1;i<=r;++i)ret=max(ret,calc(i));
89     return ret;
90 }
91 signed main()
92 {
93     //freopen("Ark.in","r",stdin);
94     register int i,opt,m,l,r,v;
97     for(i=1;i<=belong[n];++i)build(i);
99     while(m--)
100     {
102         if(opt)printf("%lld\n",query(l,r));
104     }
105 }
bzoj2388

 1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4 #include <algorithm>
5 using namespace std;
6 char B[1<<15],*S=B,*T=B;
7 #define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
8 inline int read()
9 {
10     int x=0;register char c=getc;
11     while(c<'0'||c>'9')c=getc;
12     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
13     return x;
14 }
15 #define N 1000010
16 #define inf 0x7fffffff
17 #define INF 0x7fffffffffffffffll
18 #define db double
19 #define LL long long
20 struct Vector
21 {
22     int x,y;db k;
23     Vector(int a=0,int b=0){x=a,y=b;k=((x!=0)?((db)y/x):(-inf));}
24     inline Vector operator + (const Vector &b) const{return Vector(x+b.x,y+b.y);}
25     inline Vector operator - (const Vector &b) const{return Vector(x-b.x,y-b.y);}
26     inline LL operator * (const Vector &b) const{return (LL)x*b.y-(LL)y*b.x;}
27 }pt[N],ans[N];
28 inline bool mt1(const Vector &a,const Vector &b)
29 {
30     return a.x==b.x?a.y<b.y:a.x>b.x;
31 }
32
33 int main()
34 {
35     // freopen("Ark.in","r",stdin);
36     register int i,n,top;n=read();
37     for(i=1;i<=n;++i)
39     sort(pt+1,pt+n+1,mt1);
40     for(i=1,top=0;i<=n;++i)
41     {
42         while(top>1&&(ans[top]-ans[top-1])*(pt[i]-ans[top])<0)--top;
43         ans[++top]=pt[i];
44     }
45     ans[top+1]=Vector(0,ans[top].y);
46     db l=-INF,r,k2,sum=INF;Vector tmp;
47     for(i=1;i<=top;++i)
48     {
49         r=l,l=(ans[i+1]-ans[i]).k;
50         k2=-sqrt((db)ans[i].y/ans[i].x);
51         if(l>=k2&&k2>=r)
52             sum=min(sum,ans[i].x+ans[i].y-ans[i].y/k2-ans[i].x*k2);
53         else sum=min(sum,ans[i].x+ans[i].y-ans[i].y/l-ans[i].x*l);
54         if(l>0)break;
55     }
56     printf("%.4f\n",sum);
57 }
bzoj4570

  1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <iostream>
6 using namespace std;
7 #define N 100010
8 #define eps 1e-6
9 char B[1<<15],*S=B,*T=B;
10 #define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
11 inline int read()
12 {
13     int x=0;register char c=getc;
14     while(c<'0'||c>'9')c=getc;
15     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
16     return x;
17 }
18 #define db double
19 int n,m,q,cnt,nx,ny;
20 struct point
21 {
22     db x,y;
23     point(db a=0,db b=0){x=a,y=b;}
24 }pt[N];
25 inline int sign(db a){return (a>-eps)-(a<eps);}
26 #define inf 0x7fffffff
27 inline db k(point ida,point idb)
28 {
29     if(sign(ida.x-idb.x)==0)
30         return ida.y>idb.y?-inf:inf;
31     return (ida.y-idb.y)/(ida.x-idb.x);
32 }
33 inline db sqr(db a){return a*a;}
34 inline db dis(point a,point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
35 struct node
36 {
37     int key,size;
38     node *ch[2];point x;
39     node(){key=rand();}
40     inline void update(){size=ch[0]->size+1+ch[1]->size;}
41 }*null=new node(),*root,mem[N];
42 int opt[N<<1],id[N<<1],tot,top;
43 db ans[N<<1],sum;bool vis[N];
44 inline node* newnode(point x)
45 {
46     node *o=mem+(tot++);o->size=1;
47     o->ch[0]=o->ch[1]=null;o->x=x;
48     return o;
49 }
50 inline node* merge(node *a,node *b)
51 {
52     if(a==null)return b;
53     if(b==null)return a;
54     if(a->key>b->key){a->ch[1]=merge(a->ch[1],b),a->update();return a;}
55     else{b->ch[0]=merge(a,b->ch[0]),b->update();return b;}
56 }
57 #define D pair<node*,node*>
58 inline D split(node *o,int k)
59 {
60     if(o==null)return D(null,null);D y;
61     if(o->ch[0]->size>=k)y=split(o->ch[0],k),o->ch[0]=y.second,o->update(),y.second=o;
62     else y=split(o->ch[1],k-o->ch[0]->size-1),o->ch[1]=y.first,o->update(),y.first=o;
63     return y;
64 }
65 inline bool comp(point a,point b)
66     {return sign(a.x-b.x)==0?a.y<b.y:a.x<b.x;}
67 inline int get_rank(node *o,point a)
68 {
69     if(o==null)return 0;
70     return comp(a,o->x)?get_rank(o->ch[0],a):(get_rank(o->ch[1],a)+o->ch[0]->size+1);
71 }
72 inline node* get_end(node *o)
73     {while(o->ch[1]!=null)o=o->ch[1];return o;}
74 inline node* get_start(node *o)
75     {while(o->ch[0]!=null)o=o->ch[0];return o;}
76 inline void insert(point a)
77 {
78     int rk=get_rank(root,a),sz=root->size;
79     D tmp=split(root,rk),x1=D(null,null),x2=D(null,null);
80     node *x=newnode(a),*y,*tmp1=get_end(tmp.first),*tmp2=get_start(tmp.second);
81     if(k(tmp1->x,tmp2->x)>k(tmp1->x,a)){root=merge(tmp.first,tmp.second);return;}
82     db temp=dis(tmp1->x,tmp2->x);
83     if(rk>0&&rk<sz)sum-=temp;
84     x2=split(tmp.second,1);
85     while(x2.second!=null)
86     {
87         y=get_start(x2.second);
88         if(sign( k(a,x2.first->x) - k(x2.first->x,y->x) )<0)
89             sum-=dis(x2.first->x,y->x),x2=split(x2.second,1);
90         else break;
91     }
92     x1=split(tmp.first,--rk);
93     while(x1.first!=null)
94     {
95         y=get_end(x1.first);
96         if(sign(k(y->x,x1.second->x)-k(x1.second->x,a))<0)
97             sum-=dis(y->x,x1.second->x),x1=split(x1.first,--rk);
98         else break;
99     }
100     if(x1.second!=null)
101         sum+=dis(x1.second->x,a);
102     if(x2.first!=null)
103         sum+=dis(a,x2.first->x);
104     root=merge(merge(merge(x1.first,x1.second),x),merge(x2.first,x2.second));
105 }
106 int main()
107 {
108     register int i;
112     for(i=1;i<=q;++i)
114     null->ch[0]=null->ch[1]=null;null->size=0;
115
116     root=newnode(point(nx,ny)),
117     root->ch[0]=newnode(point(0,0)),
118     root->ch[1]=newnode(point(n,0));
119     root->update();
120     sum=dis(point(0,0),point(nx,ny))+dis(point(n,0),point(nx,ny));
121     for(i=1;i<=m;++i)
122         if(!vis[i])insert(pt[i]);
123     for(i=q;i;--i)
124         if(opt[i]==1)insert(pt[id[i]]);
125         else ans[++top]=sum;
126     for(i=top;i;--i)printf("%.2f\n",ans[i]);
127 }
bzoj2300

  1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #include <cmath>
5 using namespace std;
6 #define inf 0x7fffffffll
7 #define INF 0x7fffffffffffffffll
8 #define N 400010
9 #define LL long long
10 #define sqr(a) ((LL)(a)*(a))
11 struct Vector
12 {
13     int x,y;
14     Vector(int a=0,int b=0){x=a,y=b;}
15     inline Vector operator + (const Vector &b)const {return Vector(x+b.x,y+b.y);}
16     inline Vector operator - (const Vector &b)const {return Vector(x-b.x,y-b.y);}
17     inline LL operator * (const Vector &b) const {return (LL)x*b.y-(LL)y*b.x;}
18 }vec[N];
19 inline LL Dot (const Vector &a,const Vector &b) {return (LL)a.x*b.x+(LL)a.y*b.y;}
21 struct node
22 {
23     node *ch[2];
24     int *sta,*ans1,*ans2,sz1,sz2;
25 }*root=NULL,mem[N<<1];int tot;
26 inline bool mt(const int &a,const int &b)
27     {return vec[a].x==vec[b].x?vec[a].y<vec[b].y:vec[a].x<vec[b].x;}
28 inline void insert(node *&o,int l,int r,const int &pos)
29 {
30     if(o==NULL)
31         o=mem+(tot++),o->ch[0]=o->ch[1]=NULL,
34     o->sta[pos-l]=pos;
35     if(pos==r)
36     {
37         int top=-1,len=r-l+1,i;
38         sort(o->sta,o->sta+len,mt);
39         for(top=-1,i=0;i<len;++i)
40         {
41             while(top>0&&(vec[o->ans1[top]]-vec[o->ans1[top-1]])*(vec[o->sta[i]]-vec[o->ans1[top]])>0)--top;
42             o->ans1[++top]=o->sta[i];
43         }o->sz1=top+1;
44         for(top=-1,i=0;i<len;++i)
45         {
46             while(top>0&&(vec[o->ans2[top]]-vec[o->ans2[top-1]])*(vec[o->sta[i]]-vec[o->ans2[top]])<0)--top;
47             o->ans2[++top]=o->sta[i];
48         }o->sz2=top+1;
49     }
50     if(l==r)return;
51     register int mi=(l+r)>>1;
52     if(pos<=mi)insert(o->ch[0],l,mi,pos);
53     else insert(o->ch[1],mi+1,r,pos);
54 }
55 inline LL max(const LL &a,const LL &b){return a>b?a:b;}
56 inline LL calc(const node *o,const int opt,const Vector q)
57 {
58     LL ret=-INF;
59     if(opt==1)
60     {
61         int l=0,r=o->sz1-1,ll,rr;
62         while(l+3<=r)
63         {
64             ll=(l+l+r)/3,rr=(l+r+r)/3;
65             if(Dot(vec[o->ans1[ll]],q)>Dot(vec[o->ans1[rr]],q))r=rr;
66             else l=ll;
67         }
68         for(int i=l;i<=r;++i)ret=max(ret,Dot(vec[o->ans1[i]],q));
69         return ret;
70     }
71     else
72     {
73         int l=0,r=o->sz2-1,ll,rr;
74         while(l+3<=r)
75         {
76             ll=(l+l+r)/3,rr=(l+r+r)/3;
77             if(Dot(vec[o->ans2[ll]],q)>Dot(vec[o->ans2[rr]],q))r=rr;
78             else l=ll;
79         }
80         for(int i=l;i<=r;++i)ret=max(ret,Dot(vec[o->ans2[i]],q));
81         return ret;
82     }
83 }
84 inline LL query(const node *o,int l,int r,const int &L,const int &R,const Vector &q)
85 {
86     if(L<=l&&r<=R)return q.y>0?calc(o,1,q):calc(o,2,q);
87     register int mi=(l+r)>>1;LL ret=-INF;
88     if(L<=mi)ret=query(o->ch[0],l,mi,L,R,q);
89     if(mi<R)ret=max(ret,query(o->ch[1],mi+1,r,L,R,q));
90     return ret;
91 }
92 int main()
93 {
94     // freopen("Ark.in","r",stdin);
95     register int n,i,a,b,l,r,isnot,cnt=0;char opt[3];LL ans=0;
96     scanf("%d%s",&n,opt);
97     isnot=(opt[0]!='E');
98     for(i=1;i<=n;++i)
99     {
100         scanf("%s%d%d",opt,&a,&b);
101         if(isnot)a^=(ans&inf),b^=(ans&inf);
102         if(opt[0]=='A')
103             vec[++cnt]=Vector(a,b),insert(root,1,n,cnt);
104         else
105         {
106             scanf("%d%d",&l,&r);
107             if(isnot)l^=(ans&inf),r^=(ans&inf);
108             printf("%lld\n",ans=query(root,1,n,l,r,Vector(a,b)));
109         }
110     }
111 }
bzoj3533

  1 #pragma GCC optimize("O3")
2 #include <cstdio>
3 #include <ctime>
4 #include <cstring>
5 #include <cstdlib>
6 #include <iostream>
7 #include <algorithm>
8 using namespace std;
9 #define LL long long
10 #define inf 100000001
11 #define db double
12 #define N 100010
13 char B[1<<20],*cS=B,*cT=B;
14 #define getc (cS==cT&&(cT=(cS=B)+fread(B,1,1<<20,stdin),cS==cT)?0:*cS++)
15 inline int read()
16 {
17     int x=0,f=1;register char c=getc;
18     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getc;}
19     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
20     return x*f;
21 }
22 char O[1<<22],*cI=O;
23 inline void write(LL x)
24 {
25     if(!x)*cI++='0';
26     else
27     {
28         LL y;static char c[20], *i = c;
29         while (x)y=x/10,*i++=x-y*10+'0',x=y;
30         while (i != c)*cI++=*--i;
31     }
32     *cI++='\n';
33 }
34 struct Vector
35 {
36     int x,y;
37     Vector(int a=0,int b=0){x=a,y=b;}
38     inline Vector operator + (const Vector &a){return Vector(x+a.x,y+a.y);}
39     inline Vector operator - (const Vector &a){return Vector(x-a.x,y-a.y);}
40     inline LL operator * (const Vector &a){return (LL)x*a.y-(LL)y*a.x;}
41 }p[N*2];int cnt;
42 struct node
43 {
44     int key,lc,rc,it;
45     node *ch[2];LL sum;
46     node(){key=rand();}
47     inline void update()
48     {
49         sum=ch[0]->sum+ch[1]->sum;
50         lc=ch[0]->lc?ch[0]->lc:it;
51         if(ch[0]->rc)sum+=p[it]*p[ch[0]->rc];
52         rc=ch[1]->rc?ch[1]->rc:it;
53         if(ch[1]->lc)sum+=p[ch[1]->lc]*p[it];
54     }
55 }*null,mem[N<<7];int tot;
56 inline node* newnode(int id)
57 {
58     node *o=mem+(tot++);o->ch[0]=o->ch[1]=null;
59     o->lc=o->rc=o->it=id,o->sum=0;return o;
60 }
61 #define cop(a,b) ( ((b)==null)?(a=null):a=newnode(0),*a=*b )
62 inline node* merge(node *a,node *b)
63 {
64     node *rt;
65     if(a==null)return b;
66     else if(b==null)return a;
67     else if(a->key>b->key)
68         cop(rt,a),rt->ch[1]=merge(rt->ch[1],b),rt->update();
69     else
70         cop(rt,b),rt->ch[0]=merge(a,rt->ch[0]),rt->update();
71     return rt;
72 }
73 #define D pair<node*,node*>
74 db mid;
75 inline db cross(Vector a,Vector b,Vector c,Vector d)
76 {
77     db la=(b-d)*(c-d),lb=(c-d)*(a-d);
78     return (a.x+lb/(lb+la)*(b.x-a.x));
79 }
80 inline D join(node *x,node *y)
81 {
82     int a=x->it,b=y->it,la=x->ch[0]->rc,ra=x->ch[1]->lc,lb=y->ch[0]->rc,rb=y->ch[1]->lc;
83     D ret;node *o;
84     if(ra&&lb&&(p[ra]-p[b])*(p[a]-p[b])>=0&&(p[b]-p[a])*(p[lb]-p[a])>=0)
85     {
86         db mi=cross(p[a],p[ra],p[lb],p[b]);
87         if(mi<mid)
88         {
89             cop(o,x),ret=join(o->ch[1],y);
90             o->ch[1]=ret.first,o->update(),ret.first=o;
91             return ret;
92         }
93         else
94         {
95             cop(o,y),ret=join(x,o->ch[0]);
96             o->ch[0]=ret.second,o->update(),ret.second=o;
97             return ret;
98         }
99     }
100     if(la&&(p[a]-p[la])*(p[b]-p[a])>=0)return join(x->ch[0],y);
101     if(rb&&(p[b]-p[a])*(p[rb]-p[b])>=0)return join(x,y->ch[1]);
102     if(ra&&(p[ra]-p[b])*(p[a]-p[b])>=0)
103     {
104         cop(o,x),ret=join(o->ch[1],y);
105         o->ch[1]=ret.first,o->update(),ret.first=o;
106         return ret;
107     }
108     if(lb&&(p[b]-p[a])*(p[lb]-p[a])>=0)
109     {
110         cop(o,y),ret=join(x,o->ch[0]);
111         o->ch[0]=ret.second,o->update(),ret.second=o;
112         return ret;
113     }
114     // {
115     node *oo;
116     if(x->ch[1]==null)o=x;
117     else cop(o,x),o->ch[1]=null,o->update();
118     if(y->ch[0]==null)oo=y;
119     else cop(oo,y),oo->ch[0]=null,oo->update();
120     return D(o,oo);
121     // }
122 }
123 inline node* solve(node *a,node *b)
124 {
125     if(a==null)return b;
126     if(b==null)return a;
127     mid=(p[a->rc].x+p[b->lc].x)*0.5;
128     D x=join(a,b);
129     return merge(x.first,x.second);
130 }
131 inline void init()
132 {
133     null=new node();null->ch[0]=null->ch[1]=null;
134     null->sum=0;null->lc=null->rc=null->it=0;
135 }
137 struct tree{tree *ch[2];node **sta;}Mem[N<<2];
138 inline bool mt(const int &a,const int &b)
139       {return p[a].x==p[b].x?p[a].y<p[b].y:p[a].x<p[b].x;}
140 // inline void dfs(node *o)
141 // {
142 //     if(o->ch[0]!=null)dfs(o->ch[0]);
143 //     printf("%d(%d,%d)\n",o->it,p[o->it].x,p[o->it].y );
144 //     if(o->ch[1]!=null)dfs(o->ch[1]);
145 // }
146 struct Segment_Tree
147 {
148     tree *root;
150     int id[N],rk[N];
151     inline tree* build(int l,int r)
152     {
153         tree *o=Mem+(Tot++);
155         if(l==r){o->sta[0]=lv[l];return o;}
156         register int i,mi=(l+r)>>1;
157         o->ch[0]=build(l,mi),o->ch[1]=build(mi+1,r);
158         o->sta[mi-l]=lv[mi],o->sta[mi+1-l]=lv[mi+1];
159         for(i=mi-1;i>=l;--i)o->sta[i-l]=solve(lv[i],o->sta[i-l+1]);
160         for(i=mi+2;i<=r;++i)o->sta[i-l]=solve(o->sta[i-l-1],lv[i]);
161         // printf("%d--%d\n",l,r );
162         // for(i=l;i<=r;++i)
163         //     dfs(o->sta[i-l]),printf("\n\n\n\n");
164         return o;
165     }
166     inline void build(int op)
167     {
168         register int i;head=la;
169         for(i=1;i<=n;++i)id[i]=op+i;
170         sort(id+1,id+n+1,mt);
171         for(i=1;i<=n;++i)rk[id[i]-op]=i;
172         for(i=1;i<=n;++i)lv[i]=newnode(id[i]);
173         root=build(1,n);
174     }
175     inline void query(tree *o,int l,int r,int L,int R)
176     {
177         register int mi=(l+r)>>1;
178         if(L<=mi&&mi<=R)
179             T=solve(T,o->sta[L-l]),T=solve(T,o->sta[R-l]);
180         else if(R<=mi)query(o->ch[0],l,mi,L,R);
181         else query(o->ch[1],mi+1,r,L,R);
182     }
183     inline LL getans(int op,int ge,Vector &l,Vector &r)
184     {
185         register int i,last,temp=tot;T=null;
187         sort(tmp+1,tmp+ge+1);
188         for(i=last=1;i<=ge;last=tmp[i]+1,++i)
189             if(tmp[i]>last)query(root,1,n,last,tmp[i]-1);
190         if(last<=n)query(root,1,n,last,n);
191         l=p[T->lc],r=p[T->rc];
192         tot=temp;
193         return T->sum+l*r;
194     }
195 }root1,root2;
196 int main()
197 {
198     // freopen("Ark.in","r",stdin);
199     // freopen("phantom.in","r",stdin);
200     // freopen("phantom.out","w",stdout);
202     register int i,j,ge;LL ans=n-1;
204     root1.build(0);
205     for(i=1;i<=n;++i)p[i+n].x=p[i].x,p[i+n].y=-p[i].y;
206     // printf("%d %d\n",tot,(N<<7)-tot );
207     // return 0;
208     root2.build(n);
209     Vector upl,upr,downl,downr;
210     while(m--)
211     {
213         ans=root1.getans(0,ge,upl,upr)+root2.getans(n,ge,downl,downr);
214         downl.y*=-1,downr.y*=-1;
215         ans+=(downr-downl)*(upr-downl)+(upr-downl)*(upl-downl),write(ans);
216     }
217     fwrite(O,1,cI-O,stdout);
218 }
uoj319

另外一道题……也是一个斜率优化的题目，在这里写一下

1.找到重心

2.对重心的原树父亲联通块递归执行此操作

3.dfs重心的儿子，得到需要更新的点

4.然后我们把它们按照“能更新他们的最浅深度”按从大到小排序，这样就单调了

5.然后我们维护从当前重心往他的原树祖先的一个决策凸壳，用推出来的斜率式子更新

6.递归其余的儿子联通块们

  1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 char B[1<<15],*S=B,*T=B;
6 #define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
7 template <typename _T>
8 inline _T read()
9 {
10     _T x=0;register char c=getc;
11     while(c<'0'||c>'9')c=getc;
12     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
13     return x;
14 }
15 #define LL long long
16 #define N 200010
17 #define inf 100000000000000000ll
19 LL limit[N],p[N],q[N],f[N],deep[N];
20 struct edge{int zhong,next;LL val;bool ban;}s[N];
21 inline void add(int qi,int zhong,LL val)
23 inline void dfs0(int rt)
24 {
26         deep[s[i].zhong]=deep[rt]+s[i].val,dfs0(s[i].zhong);
27 }
28 inline int max(int a,int b){return a>b?a:b;}
29 inline LL min(LL a,LL b){return a<b?a:b;}
30 inline void dfs1(int rt,int totsize,int &root)
31 {
32     size[rt]=1,maxsize[rt]=0;
34         dfs1(s[i].zhong,totsize,root),size[rt]+=size[s[i].zhong],
35         maxsize[rt]=max(maxsize[rt],size[s[i].zhong]);
36     maxsize[rt]=max(maxsize[rt],totsize-size[rt]);
37     if(maxsize[rt]<=maxsize[root])root=rt;
38 }
39 int sta[N],tot;
40 inline bool mt1(const int &a,const int &b)
41     {return deep[a]-limit[a]>deep[b]-limit[b];}
42 inline void dfs2(int rt)
43 {
44     sta[++tot]=rt;
46         if(!s[i].ban)dfs2(s[i].zhong);
47 }
48 int stack[N],top;
49 #define db double
50 inline double k(const int ida,const int idb)
51     {return (db)(f[ida]-f[idb])/(deep[ida]-deep[idb]);}
52 inline void insert(int id)
53 {
54     register int l=2,r=top,mi,ans=top+1;
55     while(l<=r)
56     {
57         mi=(l+r)>>1;
58         if( k( stack[mi],id ) >  k( stack[mi],stack[mi-1] ) )ans=mi,r=mi-1;
59         else l=mi+1;
60     }
61     stack[top=ans]=id;
62 }
63 inline int query(int id)
64 {
65     if(top==1)return stack[1];
66     register int l=1,r=top-1,mi,ans=r;
67     while(l<=r)
68     {
69         mi=(l+r)>>1;
70         if(k(stack[mi],stack[mi+1])<p[id])ans=mi,r=mi-1;
71         else l=mi+1;
72     }
73     return (k(stack[ans],stack[ans+1])<p[id])?stack[ans]:stack[ans+1];
74 }
75 inline void solve(int rt,int siz)
76 {
77     if(siz<=1)return;
78     register int i,u,v,root=0,cur;
79     dfs1(rt,siz,root);
81     solve(rt,siz-size[root]+1);
83     sort(sta+1,sta+tot+1,mt1);
84     for(cur=root,top=0,i=1;i<=tot;++i)
85     {
86         u=sta[i];
87         while(cur!=fa[rt]&&deep[u]-deep[cur]<=limit[u])
88             insert(cur),cur=fa[cur];
89         v=query(u);
90         if(  ( double)f[v]+p[u]*1.0*(deep[u]-deep[v])+q[u]     <=inf      )f[u]=min(f[u],f[v]+p[u]*(deep[u]-deep[v])+q[u]);
91     }
93         u=s[i].zhong,solve(u,size[u]);
94 }
95 int main()
96 {
97     register int i;LL tmp;
98     memset(f,0x7f,sizeof(f)),f[1]=0;
101     for(i=2;i<=n;++i)
104     dfs0(1),solve(1,n);
105     for(i=2;i<=n;++i)printf("%lld\n",f[i]);
106 }
bzoj3672

posted @ 2018-01-19 19:45 LadyLex 阅读(...) 评论(...) 编辑 收藏