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