[不完全动态凸包]SGU277

由于SDOI某题是线段树套不完全动态凸包,以前没写过,所以抱着试试的心态去写了写。

(感觉还是蛮好写的对吧?)

由于不想手写平衡树,又因为有一个二分斜率的东西,所以set要搞一个开关。

于是写啊写,搞了好久,终于对了。

然后悲剧发生了。。。

常数太大,死交不过。尼玛?根本优化不动。

一怒一下,改成手写。。。然后悲剧又发生了。。。

还是常数太大,还是死交不过。。。。尼玛?!!!!

唉。。。

我的做法是分别维护上凸和下凸(两者只是叉积符号相反)。

set里按(x,y)升序排,插入就向前向后维护一下。

set比较烦人的就是begin和end等等判越界的问题。

然后就顺手把SGU277 A了。

说明正确性和复杂度还是没问题的。

 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
",ans[1]-ans[0]);}
48     return 0;
49 }
SGU277
  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
",ans);
109         }
110     }
111         
112     scanf("
");
113     return 0;
114 }
SDOIR1D2_TLE
原文地址:https://www.cnblogs.com/oldmanren/p/3667663.html