[不完全动态凸包]SGU277
由于SDOI某题是线段树套不完全动态凸包,以前没写过,所以抱着试试的心态去写了写。
(感觉还是蛮好写的对吧?)
由于不想手写平衡树,又因为有一个二分斜率的东西,所以set要搞一个开关。
于是写啊写,搞了好久,终于对了。
然后悲剧发生了。。。
常数太大,死交不过。尼玛?根本优化不动。
一怒一下,改成手写。。。然后悲剧又发生了。。。
还是常数太大,还是死交不过。。。。尼玛?!!!!
唉。。。
我的做法是分别维护上凸和下凸(两者只是叉积符号相反)。
set里按(x,y)升序排,插入就向前向后维护一下。
set比较烦人的就是begin和end等等判越界的问题。
然后就顺手把SGU277 A了。
说明正确性和复杂度还是没问题的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 using namespace std; 5 #define mp make_pair 6 #define x first 7 #define y second 8 template<class T> inline void read(T&x){bool fu=0;char c;for(c=getchar();c<=32;c=getchar());if(c=='-')fu=1,c=getchar();for(x=0;c>32;c=getchar())x=x*10+c-'0';if(fu)x=-x;}; 9 typedef long long ll; 10 typedef pair<ll,ll> node; 11 typedef set<node>::iterator sit; 12 13 ll operator*(node a,node b){return 1LL*a.x*b.y-1LL*a.y*b.x;} 14 node operator-(node a,node b){return mp(a.x-b.x,a.y-b.y);} 15 void Read(node&a){read(a.x),read(a.y);} 16 const ll INF=ll(1e18); 17 int ca,i;char ch;int F;ll ans[2]; 18 set<node> S[2]; 19 node now,oo=mp(INF,INF),zero;sit it,pos;node p1,p2; 20 #define B S[t].begin() 21 #define E S[t].end() 22 #define IN insert 23 #define ER erase 24 #define up(x,y) x=max(x,y) 25 #define k0 (t==0?1:-1) 26 #define L(a) ((a)==S[t].begin()?oo:*(pos=a,--pos)) 27 #define R(a) ((pos=a,++pos)==S[t].end()?oo:*pos) 28 #define LB S[t].lower_bound(now) 29 #define FI S[t].find(now) 30 int xj(node a,node b,node c){if(max(max(a,b),c)==oo)return 0; return ((b-a)*(c-a)>0)*2-1;}// >0:1 <0:-1 error:0 31 #define C(p,K) { p1=L(p);if(p1==oo)p1=zero;\ 32 p2=R(p);if(p2==oo)p2=zero;\ 33 ans[t]+=K*((p1*(*p)+(*p)*p2)-p1*p2); } 34 void ins() 35 { 36 for(int t=0;t<=1;t++){ 37 if((it=LB)!=E&&((*it)==now||xj(L(it),now,*it)*k0>0))continue; 38 if((it=LB)!=E)for(;xj(now,*it,R(it))*k0>0;S[t].erase(it++))C(it,-1); 39 if((it=LB)!=B)for(it--;xj(L(it),*it,now)*k0>0;S[t].erase(it--))C(it,-1); 40 S[t].IN(now);C(FI,1); 41 } 42 } 43 44 int main() 45 { 46 for(i=0;i<=2;i++)Read(now),ins(); 47 for(read(ca);ca;ca--){Read(now),ins();printf("%lld\n",ans[1]-ans[0]);} 48 return 0; 49 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<set> 5 #include<iostream> 6 using namespace std; 7 #define mp make_pair 8 #define rep(i,x,y) for(i=(x);i<=(y);i++) 9 #define _rep(i,x,y) for(i=(x);i>=(y);i--) 10 #define REP(i,x,y) for(int i=(x);i<=(y);i++) 11 #define _REP(i,x,y) for(int i=(x);i>=(y);i--) 12 #define CL(S,x) memset(S,x,sizeof(S)) 13 #define CP(S1,S2) memcpy(S1,S2,sizeof(S2)) 14 #define ALL(x,S) for(x=S.begin();x!=S.end();x++) 15 #define max3(a,b,c) max(max(a,b),c) 16 typedef long long ll; 17 typedef double ld; 18 19 inline char getc(){char c;for(c=getchar();c<=32;c=getchar());return c;} 20 21 const int N=400010; 22 const ll INF=ll(1e18); 23 const ld eps=1e-6; 24 const int 25 int thec=0x7fffffff; 26 27 int ca,ca0,n,m,i,j,k,l,r;char ch;int F;ll ans; 28 29 #define DC(x) x^=(ans&thec) 30 template<class T> inline void read(T&x){bool fu=0;char c;for(c=getchar();c<=32;c=getchar());if(c=='-')fu=1,c=getchar();for(x=0;c>32;c=getchar())x=x*10+c-'0';if(fu)x=-x;DC(x);}; 31 template<class T> inline void read(T&x,T&y){read(x);read(y);}; 32 33 struct node{ll x,y;ld k;}; 34 typedef set<node>::iterator sit; 35 node u,now,oo=(node){INF,INF,0};sit it,it1,it2,pos; 36 #define B S[t].begin() 37 #define E S[t].end() 38 #define LB lower_bound 39 #define IN insert 40 #define ER erase 41 #define up(x,y) x=max(x,y) 42 43 bool operator<(node a,node b){if(F==0)return mp(a.x,a.y)<mp(b.x,b.y);else if(F==1)return a.k>b.k;else return a.k<b.k;} 44 bool operator==(node a,node b){return mp(a.x,a.y)==mp(b.x,b.y);} 45 void Read(node&a){read(a.x,a.y);} 46 ll operator*(node a,node b){return 1LL*a.x*b.y-1LL*a.y*b.x;} 47 node operator-(node a,node b){return (node){a.x-b.x,a.y-b.y,0};} 48 int xj(node a,node b,node c){if(max3(a,b,c)==oo)return 0; return ((b-a)*(c-a)>0)*2-1;}// >0:1 <0:-1 error:0 49 ld calc(node a,node b){return ld(b.y-a.y)/(b.x-a.x+eps);} 50 ll mul(node a,node b){return a.x*b.x+a.y*b.y;} 51 52 void P(node a){cout<<a.x<<','<<a.y<<' ';} 53 void Pl(node a){cout<<a.x<<','<<a.y<<endl;} 54 55 vector<int> V[1<<20]; 56 struct tnode 57 { 58 set<node> S[2]; 59 #define k0 (t==0?1:-1) 60 #define L(a) ((a)==S[t].begin()?oo:*(pos=a,--pos)) 61 #define R(a) ((pos=a,++pos)==S[t].end()?oo:*pos) 62 void ins() 63 { 64 REP(t,0,1){ 65 it=S[t].LB(now); 66 if(it!=E&&((*it)==now||xj(L(it),now,*it)*k0>0))continue; 67 if(it!=E)for(;xj(now,*it,R(it))*k0>0;S[t].erase(it++)); 68 if(it!=B)for(it--;xj(L(it),*it,now)*k0>0;S[t].erase(it--)); 69 if((it1=S[t].LB(now))!=E){u=*it1;S[t].ER(it1);u.k=calc(now,u);S[t].IN(u);} 70 if((it2=S[t].LB(now))!=B){u=*(--it2);now.k=calc(u,now);}else now.k=(t==0)?INF:-INF; 71 S[t].IN(now); 72 } 73 } 74 void find() 75 { 76 now.k=ld(-now.x)/(now.y+(now.y==0)*eps); 77 REP(t,0,1){ 78 F=t+1;it=S[t].LB(now); 79 if(it!=E) up(ans,mul(*it,now)); 80 if(it!=B) up(ans,mul(*(--it),now)); 81 } 82 F=0; 83 } 84 }T[1<<20]; 85 86 void tins(int i,int tx,int ty,int d){ 87 T[i].ins(); 88 if(tx!=ty)if(d<=(tx+ty)/2)tins(i*2,tx,(tx+ty)/2,d);else tins(i*2+1,(tx+ty)/2+1,ty,d); 89 } 90 void find(int i,int tx,int ty,int l,int r){ 91 if(ty<l||tx>r)return; 92 if(tx>=l&&ty<=r){T[i].find();return;} 93 find(i*2,tx,(tx+ty)/2,l,r);find(i*2+1,(tx+ty)/2+1,ty,l,r); 94 } 95 96 97 int main() 98 { 99 //freopen("vset.in","r",stdin);freopen("vset.out","w",stdout); 100 read(ca);n=ca;ch=getc();if(ch=='E')thec=0; 101 rep(ca0,1,ca) 102 { 103 ch=getc(); 104 if(ch=='A')Read(now),tins(1,1,n,++m); 105 else if(ch=='Q') 106 { 107 Read(now);read(l,r); 108 ans=-INF;find(1,1,n,l,r);printf("%I64d\n",ans); 109 } 110 } 111 112 scanf("\n"); 113 return 0; 114 }