二进制分组思想很简单,就是把下标拆成几个2的次幂的和,对每个2的次幂维护答案,复杂度是暴力重构一组的复杂度乘log(如果可以归并可能会少个log)。

这里其实想整理下一些修改独立的数据结构题的套路。

离线算法:

  (1) 只有插入:CDQ分治。

  (2) 有删除:

    支持删除操作:CDQ分治。

    不支持删除但支持按插入反序撤销:线段树分治。

    不支持删除与撤销:时间倒流。

  (3)每次询问的是某个修改区间内的所有修改都生效时的答案:分治+前后缀和。

  (4)答案可二分、修改的贡献具有交换律、结合律、可加性:整体二分。

  (5)每次询问的是一个区间:莫队、回滚莫队。

在线算法: (1) 随机。 (2) 二进制分组。

 

二进制分组题表:

[BZOJ4140]共点圆加强版

论文题。化下式子发现是一个半平面,于是问题变为在线插入点并询问某个半平面内是否有点。维护点集的凸包,每次合并两组的时候暴力重构即可。

 1 #include<cstdio>
 2 #include<vector>
 3 #include<algorithm>
 4 #define pb push_back
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 using namespace std;
 7 
 8 const int N=500100;
 9 double x,y;
10 int n,ans,top,op;
11 struct P{ double x,y; }a[N];
12 bool operator <(const P &a,const P &b){ return a.x==b.x ? a.y<b.y : a.x<b.x; }
13 
14 double sl(P a,P b){
15     if (a.x==b.x) return a.y>b.y ? 1e18 : -1e18;
16     return (a.y-b.y)/(a.x-b.x);
17 }
18 
19 struct Gr{
20     vector<P>p,q; int tot,top;
21     void ins(P x){ tot++; p.pb(x); }
22     void clear(){ p.clear(); q.clear(); tot=top=0; }
23 
24     void build(){
25         sort(p.begin(),p.end()); top=1; q.clear(); q.pb(p[0]);
26         rep(i,1,tot-1){
27             while (top>1 && sl(q[top-1],q[top-2])-sl(q[top-1],p[i])>=0) top--,q.pop_back();
28             q.pb(p[i]); top++;
29         }
30     }
31 
32     bool que(double x,double y){
33         double k=-x/y; int l=1,r=top-1,res=0;
34         while (l<=r){
35             int mid=(l+r)>>1;
36             if (sl(q[mid],q[mid-1])<=k) l=mid+1,res=mid; else r=mid-1;
37         }
38         return 2*x*q[res].x+2*y*q[res].y>=x*x+y*y;
39     }
40 }B[50];
41 
42 void ins(double x,double y){
43     B[++top].ins((P){x,y});
44     while (top>1 && B[top].tot==B[top-1].tot){
45         rep(i,0,B[top].tot-1) B[top-1].ins(B[top].p[i]);
46         B[top--].clear();
47     }
48     B[top].build();
49 }
50 
51 bool que(double x,double y){
52     if (!top) return 0;
53     rep(i,1,top) if (!B[i].que(x,y)) return 0;
54     return 1;
55 }
56 
57 int main(){
58     scanf("%d",&n);
59     rep(i,1,n){
60         scanf("%d%lf%lf",&op,&x,&y); x+=ans; y+=ans;
61         if (!op) ins(x,y);
62         else if (que(x,y)) ans++,puts("Yes"); else puts("No");
63     }
64     return 0;
65 }
BZOJ4140

相关文章:

  • 2021-08-04
  • 2022-12-23
  • 2021-08-03
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-01-24
  • 2022-02-05
  • 2021-11-07
  • 2022-01-27
  • 2022-12-23
相关资源
相似解决方案