• P4848 崂山白花蛇草水


    题面

    • 平面是二维的,第 K 大是相对的。

    • 单纯的 K- D 似乎并不能解决(反正我不会)。

    • 第 K 大和二分是紧密相关的。

    • 二分之后的判定就是一个二维数点问题。

    • 所以我们可以线段树套 K-D tree 。

      1 #include<bits/stdc++.h>
      2 #define ls son[u][0]
      3 #define rs son[u][1]
      4 using namespace std;
      5 const double dat=0.8;
      6 const int N=1000000000;
      7 int n,m,cnt,tot,rt,ans;
      8 int opt,x[2],y[2],w,sum;
      9 int root[5000050];
     10 int ch[5000050][2];
     11 int val[5000050][2],siz[5000050];
     12 int L[5000050][2],R[5000050][2];
     13 int son[5000050][2];
     14 int t[5000050],top,K;
     15 bool cmp(int a,int b)
     16 {
     17     return val[a][K]<val[b][K];
     18 }
     19 void pushup(int u)
     20 {
     21     siz[u]=siz[ls]+siz[rs]+1;
     22     for(int i=0;i<=1;++i)
     23     {
     24         L[u][i]=min(val[u][i],min(L[ls][i],L[rs][i]));
     25         R[u][i]=max(val[u][i],max(R[ls][i],R[rs][i]));
     26     }
     27 }
     28 void dfs(int u)
     29 {
     30     t[++top]=u;
     31     if(ls)    dfs(ls);
     32     if(rs)    dfs(rs);
     33 }
     34 void calc_build(int &u,int l,int r,int k)
     35 {
     36     if(l>r)    
     37     {
     38         u=0;
     39         return ;
     40     }
     41     int mid=(l+r)>>1;    K=k;
     42     sort(t+l,t+r+1,cmp);    u=t[mid];
     43     calc_build(ls,l,mid-1,k^1);
     44     calc_build(rs,mid+1,r,k^1);
     45     pushup(u);
     46 }
     47 void calc_rebuild(int &u,int k)
     48 {
     49     t[top=1]=tot;dfs(u);
     50     calc_build(u,1,top,k);
     51 }
     52 void calc_insert(int &u,int k)
     53 {
     54     if(!u)
     55         u=tot;
     56     else if(val[tot][k]<val[u][k])
     57     {
     58         if(siz[ls]>siz[u]*dat)
     59         {
     60             calc_rebuild(u,k);
     61             return ;
     62         }
     63         else
     64             calc_insert(ls,k^1);
     65     }
     66     else
     67     {
     68         if(siz[rs]>siz[u]*dat)
     69         {
     70             calc_rebuild(u,k);
     71             return ;
     72         }
     73         else
     74             calc_insert(rs,k^1);
     75     }
     76     pushup(u);
     77     return ;
     78 }
     79 void calc_add(int &u,int l,int r,int pos)
     80 {
     81     if(!u)    u=++cnt;
     82     ++tot;
     83     val[tot][0]=x[0];
     84     val[tot][1]=x[1];
     85     calc_insert(root[u],0);
     86     if(l==r)    return ;
     87     int mid=(l+r)>>1;
     88     if(pos<=mid)    calc_add(ch[u][0],l,mid,pos);
     89     else    calc_add(ch[u][1],mid+1,r,pos);
     90 }
     91 bool flagALL;
     92 bool flagALO;
     93 bool flagBIT;
     94 void check(int u)
     95 {
     96     flagALL=true;    flagBIT=true;    flagALO=true;
     97     for(int i=0;i<=1;++i)
     98         if(L[u][i]<x[i]||R[u][i]>y[i])
     99         {
    100             flagALL=false;
    101             if(val[u][i]>y[i]||val[u][i]<x[i])
    102             {
    103                 flagALO=false;
    104                 if(L[u][i]>y[i]||R[u][i]<x[i])
    105                     flagBIT=false;
    106             }
    107         }
    108 }
    109 void ask(int u)
    110 {
    111     if(!u)    return ;
    112     check(u);
    113     if(flagALL)
    114     {
    115         sum+=siz[u];
    116         return ;
    117     }
    118     if(flagALO)
    119         sum+=1;
    120     if(!flagBIT)
    121         return ;
    122     ask(ls);    ask(rs);
    123 }
    124 void calc_ask(int u,int l,int r)
    125 {
    126     if(l==r)
    127     {
    128         sum=0;    ask(root[u]);
    129         ans=sum>=w? l:0;
    130         return ;
    131     }
    132     int mid=(l+r)>>1;
    133     sum=0;    ask(root[ch[u][1]]);
    134     if(w>sum)
    135     {
    136         w-=sum;
    137         calc_ask(ch[u][0],l,mid);
    138     }
    139     else
    140         calc_ask(ch[u][1],mid+1,r);
    141 }
    142 int main()
    143 {
    144     L[0][0]=N;    L[0][1]=N;
    145     R[0][0]=0;    R[0][1]=0;
    146     scanf("%d%d",&n,&m);
    147     while(m--)
    148     {
    149         scanf("%d%d%d",&opt,&x[0],&x[1]);
    150         x[0]^=ans;    x[1]^=ans;
    151         if(opt==1)
    152         {
    153             scanf("%d",&w);    w^=ans;
    154             calc_add(rt,1,N,w);
    155         }
    156         else
    157         {
    158             scanf("%d%d%d",&y[0],&y[1],&w);
    159             y[0]^=ans;    y[1]^=ans;    w^=ans;
    160             calc_ask(rt,1,N);
    161             if(!ans)    printf("NAIVE!ORZzyz.
    ");
    162             else        printf("%d
    ",ans);
    163         }
    164     }
    165     return 0;
    166 }
    View Code
  • 相关阅读:
    如何在js中使用递归
    基于angular写的一个todolist
    使用github参与开源项目
    用sass写栅格系统
    Activity返回按钮
    Listview优化MovieListAdapter的使用
    [强悍]listview下拉刷新,上拉加载更多组件版
    Google自己的下拉刷新组件SwipeRefreshLayout
    当ListView有Header时,onItemClick里的position不正确
    tabhost练习,剥离自“去哪儿”
  • 原文地址:https://www.cnblogs.com/wyher/p/10434413.html
Copyright © 2020-2023  润新知