HDU 6649 Data Structure Problem(凸包+平衡树)

首先可以证明,点积最值的点对都是都是在凸包上,套用题解的证明:假设里两个点都不在凸包上, 考虑把一个点换成凸包上的点(不动的那个点), 不管你是要点积最大还是最小, 你都可以把那个不动的点跟原点拉一条直线, 然后把所有的点投影到这条直线上, 要找的无非就是这条直线最前面或者最后面的两个点.这两个点不可能是不在凸包上的点.同理我们可以把另一个点移到凸包上.

由于数据随机生成,那么生成凸包上的点的个数的期望是logn,而且删的点落在凸包上的概率是logn/n,所以只需要对每次删点和加点暴力重构凸包即可。但是删点过程要求剩下的第k个还在的点,那么这就需要用平衡树去维护第k个点的值,直接用stl内部的红黑树。

  1 //        ——By DD_BOND
  2 
  3 #include<ext/pb_ds/assoc_container.hpp>
  4 //#include<bits/stdc++.h>
  5 //#include<unordered_map>
  6 //#include<unordered_set>
  7 #include<functional>
  8 #include<algorithm>
  9 #include<iostream>
 10 //#include<ext/rope>
 11 #include<iomanip>
 12 #include<climits>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<cstddef>
 16 #include<cstdio>
 17 #include<memory>
 18 #include<vector>
 19 #include<cctype>
 20 #include<string>
 21 #include<cmath>
 22 #include<queue>
 23 #include<deque>
 24 #include<ctime>
 25 #include<stack>
 26 #include<map>
 27 #include<set>
 28 
 29 #define fi first
 30 #define se second
 31 #define MP make_pair
 32 #define pb push_back
 33 
 34 #pragma GCC optimize(3)
 35 #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
 36 
 37 using namespace std;
 38 using namespace __gnu_pbds;
 39 using Tree=tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>;
 40 
 41 typedef long long ll;
 42 typedef pair<int,int> P;
 43 typedef pair<ll,ll> Pll;
 44 typedef unsigned long long ull;
 45 
 46 const int lim=1e9;
 47 const ll LLMAX=2e18;
 48 const int MAXN=2e5+10;
 49 const double eps=1e-8;
 50 const double pi=acos(-1.0);
 51 const unsigned mul=20190812;
 52 const ll INF=0x3f3f3f3f3f3f3f3f;
 53 
 54 inline int dcmp(double x){
 55     if(fabs(x)<eps)    return 0;
 56     return (x>0? 1: -1);
 57 }
 58 
 59 inline double sqr(double x){ return x*x; }
 60 
 61 Tree t;
 62 
 63 struct Point{
 64     ll x,y; int id;
 65     Point(){ x=0,y=0; }
 66     Point(ll _x,ll _y):x(_x),y(_y){}
 67     bool operator ==(const Point &b)const{
 68         return x==b.x&&y==b.y;
 69     }
 70     bool operator <(const Point &b)const{
 71         return (x-b.x)==0? (y-b.y)<0 : x<b.x;
 72     }
 73     Point operator -(const Point &b)const{
 74         return Point(x-b.x,y-b.y);
 75     }
 76 };
 77 
 78 inline ll cross(Point a,Point b){    //叉积
 79     return a.x*b.y-a.y*b.x;
 80 }
 81 
 82 inline ll dot(Point a,Point b){    //点积
 83     return a.x*b.x+a.y*b.y;
 84 }
 85 
 86 Point tmp[MAXN];
 87 int convex_hull(Point *p,int n,Point *ch){    //求凸包
 88     int m=0;
 89     sort(p,p+n);
 90     for(int i=0;i<n;i++){
 91         while(m>1&&cross(tmp[m-1]-tmp[m-2],p[i]-tmp[m-1])<=0)    m--;
 92         tmp[m++]=p[i];
 93     }
 94     int k=m;
 95     for(int i=n-2;i>=0;i--){
 96         while(m>k&&cross(tmp[m-1]-tmp[m-2],p[i]-tmp[m-1])<=0)    m--;
 97         tmp[m++]=p[i];
 98     }
 99     if(n>1)    m--;
100     for(int i=0;i<m;i++)    ch[i]=tmp[i];
101     return m;
102 }
103 
104 class Magic{
105 public:
106     Magic(unsigned state):state(state),ans(0){}
107     unsigned long long retrieve(){
108         unsigned modulo=0x7fffffff;
109         state=((unsigned long long)state*mul+ans)%modulo;
110         unsigned high=state;
111         state=((unsigned long long)state*mul+ans)%modulo;
112         return high*modulo+state;
113     }
114     int retrieve(int a,int b){
115         return (int)(retrieve()%(b-a+1))+a;
116     }
117     void submit(unsigned k){
118         ans=ans*mul+k;
119     }
120     unsigned retrieveAns(){
121         return ans;
122     }
123 private:
124     unsigned state,ans;
125 };
126 
127 class DataStructure{
128 public:
129     int n,m;
130     Point point[MAXN],rec[MAXN];
131     DataStructure(){ n=m=0; }
132     void add(int x,int y){
133         t.insert(++m);
134         rec[m]=Point(x,y);
135         point[n]=Point(x,y);
136         point[n++].id=m;
137         n=convex_hull(point,n,point);
138     }
139     void erase(int r){
140         r=*t.find_by_order(r-1);
141         t.erase(r);
142         for(int i=0;i<n;i++)
143             if(point[i].id==r){
144                 n=0;
145                 for(auto i:t)   point[n]=rec[i],point[n++].id=i;
146                 n=convex_hull(point,n,point);
147                 break;
148             }
149     }
150     P query(){
151         P ans(0,0); ll len=LLMAX;
152         for(int i=0;i<n;i++)
153             for(int j=0;j<n;j++){
154                 ll dis=dot(point[i],point[j]);
155                 if(dis<len){
156                     len=dis;
157                     ans=P(point[i].id,point[j].id);
158                 }
159             }
160         if(ans.fi>ans.se)   swap(ans.fi,ans.se);
161         return ans;
162     }
163 };
164 
165 int main(void){
166     int q;    cin>>q;
167     for(int k=0;k<q;++k){
168         t.clear();
169         unsigned state; string s;   cin>>state>>s;
170         DataStructure ds;   Magic magic(state);
171         for(char c:s){
172             if(c=='a'){
173                 int x=magic.retrieve(-lim,lim);
174                 int y=magic.retrieve(-lim,lim);
175                 ds.add(x,y);
176             }
177             else if(c=='e'){
178                 unsigned pos = magic.retrieve(1,t.size());
179                 ds.erase(pos);
180             }
181             else if(c=='q'){
182                 auto best=ds.query();
183                 magic.submit(best.first);
184                 magic.submit(best.second);
185             }
186         }
187         cout<<magic.retrieveAns()<<endl;
188     }
189 }

 

posted @ 2019-08-13 16:41  DD_BOND  阅读(515)  评论(0编辑  收藏  举报