• bzoj3533【Sdoi2014】向量集


    题目描述

    维护一个向量集合,在线支持以下操作:
    "A x y (|x|,|y| < =10^8)":加入向量(x,y);
    " Q x y l r (|x|,|y| < =10^8,1 < =L < =R < =T,其中T为已经加入的向量个数)询问第L个到第R个加入的向量与向量(x,y)的点积的最大值。
        集合初始时为空


    输入格式

        输入的第一行包含整数N和字符s,分别表示操作数和数据类别;
        接下来N行,每行一个操作,格式如上所述。
        请注意s≠'E'时,输入中的所有整数都经过了加密。你可以使用以下程序
    得到原始输入:
    inline int decode (int x long long lastans) {
         return x ^ (lastans & Ox7fffffff);
    }
    function decode
    begin
        其中x为程序读入的数,lastans为之前最后一次询问的答案。在第一次询问之前,lastans=0。

    注:向量(x,y)和(z,W)的点积定义为xz+yw。


    输出格式

      对每个Q操作,输出一个整数表示答案。

    提示

    1 < =N < =4×10^5

    新加数据一组..2015.315


    • 题解

      • 设当前向量为$(a,b)$集合中向量为$(x,y)$,设$z = ax+by$,有$y =  - frac{a}{b} x + frac{z}{b}$
      • 最优化$z$:
        • 当$b>0$即求过集合$S$中的某个点且斜率为$ - frac{a}{b}$的直线$y$截距最大的为哪条,答案一定在上凸包上;
        • 同理$b<0$时求截距最小的为哪条;
        • $b==0$随便哪条查即可;
      • 如果维护了区间$[L,R]$的凸包就可以在里面三分;
      • 应该是可以用线段树套$splay$参照$bzoj2300$但是效率比较低;
      • 考虑直接用线段树,由于标号是顺序更新,所以一段区间的最后一个点被加入后再求区间的凸包,查询线段树查询+三分;
      • 实现上凸包的排序可以用归并,(然而并没有快TAT);
      • O(n log^2   n )
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 #include<cmath>
      7 #include<vector>
      8 #include<stack>
      9 #include<map>
     10 #include<set>
     11 #define Run(i,l,r) for(int i=l;i<=r;i++)
     12 #define Don(i,l,r) for(int i=l;i>=r;i--)
     13 #define ll long long
     14 #define ld long double
     15 #define mk make_pair
     16 #define fir first
     17 #define sec second
     18 #define il inline
     19 #define rg register
     20 #define pb push_back
     21 #define ls (k<<1)
     22 #define rs (k<<1|1)
     23 using namespace std;
     24 const int N=400010;
     25 const ll inf=1e18;
     26 int n,cnt,sz[N<<2],L[2][N<<2],R[2][N<<2];
     27 ll ans=0;
     28 struct poi{
     29     ll x,y;
     30     poi(int _x=0,int _y=0):x(_x),y(_y){};
     31     poi operator-(const poi&A)const{return poi(x-A.x,y-A.y);}
     32     bool operator <(const poi&A)const{return x==A.x?y<A.y:x<A.x;}
     33 }con[19][N],Q,tmp[19][N],p[N];
     34 il char gc(){
     35     static char*p1,*p2,s[1000000];
     36     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
     37     return(p1==p2)?EOF:*p1++;
     38 }
     39 il int rd(){
     40     int x=0,f=1; char c=gc();
     41     while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
     42     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
     43     return x*f;
     44 }
     45 il ll dot(poi A,poi B){return (ll)A.x*B.x+(ll)A.y*B.y;}
     46 il ll crs(poi A,poi B){return (ll)A.x*B.y-(ll)A.y*B.x;}
     47 il ll max(ll x,ll y){return x>y?x:y;}
     48 il void build(int k,int d,int l,int r){
     49     int mid=(l+r)>>1,idl=l,idr=mid+1,id=l,top,lst;
     50     for(;idl<=mid||idr<=r;){
     51         if(idr>r||(idl<=mid&&tmp[d+1][idl]<tmp[d+1][idr]))
     52         tmp[d][id]=tmp[d+1][idl],id++,idl++;
     53         else 
     54         tmp[d][id]=tmp[d+1][idr],id++,idr++;
     55     }
     56     con[d][L[0][k]=top=l]=tmp[d][l];
     57     for(rg int i=l+1;i<=r;++i){
     58         while(top>l&&crs(con[d][top]-con[d][top-1],tmp[d][i]-con[d][top])<=0)top--;
     59         con[d][++top]=tmp[d][i];
     60     }
     61     R[0][k]=L[1][k]=lst=top;
     62     for(rg int i=r-1;i>=l;--i){
     63         while(top>lst&&crs(con[d][top]-con[d][top-1],tmp[d][i]-con[d][top])<=0)top--;
     64         if(i!=l)con[d][++top]=tmp[d][i];
     65     }
     66     R[1][k]=top;
     67 }
     68 il void ask(int k,int d,int typ){
     69     int l=L[typ][k],r=R[typ][k];
     70     while(r-l>=3){
     71         int mid=(r-l)/3,mid1=l+mid,mid2=r-mid;
     72         if(dot(con[d][mid1],Q)<dot(con[d][mid2],Q))l=mid1;
     73         else r=mid2;
     74     }
     75     for(rg int i=l;i<=r;++i)ans=max(ans,dot(con[d][i],Q));
     76     ans=max(ans,dot(con[d][L[0][k]],Q));
     77 }
     78 il void update(int k,int d,int l,int r,int x){
     79     if(l==r){
     80         sz[k]=1;
     81         L[0][k]=L[1][k]=R[0][k]=R[1][k]=x;
     82         tmp[d][x]=con[d][x]=p[x];
     83     }
     84     else{
     85         int mid=(l+r)>>1;
     86         if(x<=mid)update(ls,d+1,l,mid,x);
     87         else update(rs,d+1,mid+1,r,x);
     88         sz[k]=sz[ls]+sz[rs];
     89         if(sz[k]==r-l+1)build(k,d,l,r);
     90     }
     91 }
     92 il void query(int k,int d,int l,int r,int x,int y){
     93     if(l==x&&r==y){ask(k,d,Q.y>0);}
     94     else{
     95         int mid=(l+r)>>1;
     96         if(y<=mid)query(ls,d+1,l,mid,x,y);
     97         else if(x>mid)query(rs,d+1,mid+1,r,x,y);
     98         else query(ls,d+1,l,mid,x,mid),query(rs,d+1,mid+1,r,mid+1,y);
     99     }
    100 }
    101 int main(){
    102     #ifndef ONLINE_JUDGE
    103     freopen("bzoj3533.in","r",stdin);
    104     freopen("bzoj3533.out","w",stdout);
    105     #endif
    106     char ch,tp;int x,y,l,r;
    107     n=rd();tp=gc();
    108     while(!isalpha(tp))tp=gc();
    109     for(rg int i=1;i<=n;++i){
    110         ch=gc();while(!isalpha(ch))ch=gc();
    111         if(ch=='A'){
    112             x=rd();y=rd();
    113             if(tp!='E')x^=ans,y^=ans;
    114             p[++cnt]=poi(x,y);
    115             update(1,0,1,n,cnt);
    116         }else{
    117             x=rd();y=rd();l=rd();r=rd();
    118             if(tp!='E')x^=ans,y^=ans,l^=ans,r^=ans;
    119             Q=(poi){x,y}; 
    120             ans = -inf;
    121             query(1,0,1,n,l,r);
    122             printf("%lld
    ",ans);
    123             ans &= 0x7fffffff;
    124         }
    125     } 
    126     return 0;
    127 }//by tkys_Austin;
    bzoj3533
  • 相关阅读:
    WP7应用开发笔记插曲 小心使用MessageBox
    WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片
    WP7应用开发笔记(10) 导航
    Bangumi 番組計劃 WP手机客户端发布
    WP7应用开发笔记(17) 提交应用
    WP7应用开发笔记(8) IP输入框控件
    从FLC中学习的设计模式系列结构型模式(2)装饰
    Windows Phone Toolkit for WP8 已经出了
    狂神说HTML笔记
    期待
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10280315.html
Copyright © 2020-2023  润新知