zoukankan      html  css  js  c++  java
  • BZOJ 1901 Zju2112 Dynamic Rankings 题解

    题意:带修改不带插入的区间k大。

    裸的可持久化线段树。。由于有修改,要用树状数组维护。其它跟不带修改的可持久化线段树一样。

    因为我没有找到网上用指针写的代码。。CLJ写这道题也用的不是可持久化线段树,于是我就没有任何模板可以参照。。就参考网上数组版的自己脑补了一个指针版。。你们就可以看到代码优美度下降了好多。

    由于数字范围很大,我们需要把所有输入读进来然后离散化。。不离散化的话就要动态开点(这个我暂时还不会)

    这份代码用的空间比较多。。在zju是A不了的,需要空间优化(怎么优化我也不知道)

      1 #include<cstdio>
      2 #include<algorithm>
      3 const int MAXN=10000+5;
      4 const int INF=~0U>>1;
      5 const int BUFFER_SIZE=10000;
      6 const int MAXM=10000+5;
      7 struct Tree{
      8     Tree* pl,*pr;
      9     int l,r,sum;
     10     Tree* set(int _l,int _r,Tree* _pl,Tree* _pr)
     11     {
     12         l=_l;r=_r;pl=_pl;pr=_pr;
     13         sum=pl->sum+pr->sum;
     14         return this;
     15     }
     16     Tree* set(int _l,int _r,int all);
     17     Tree* add(int pos,int ad);
     18 };
     19 Tree* buffer=0,*cur;
     20 inline Tree* get()
     21 {
     22     if(!buffer || cur-buffer==BUFFER_SIZE)
     23         buffer=new Tree[BUFFER_SIZE],cur=buffer;
     24     return cur++;
     25 }
     26 Tree* Tree::set(int _l,int _r,int all)
     27 {
     28     l=_l;r=_r;
     29     if(l+1==r) sum=all;
     30     else
     31     {
     32         int m=(l+r)>>1;
     33         pl=get()->set(l,m,all);
     34         pr=get()->set(m,r,all);
     35         sum=pl->sum+pr->sum;
     36     }
     37     return this;
     38 }
     39 Tree* Tree::add(int pos,int ad)
     40 {
     41     if(l+1==r) return get()->set(l,r,sum+ad);
     42     int m=(l+r)>>1;
     43     if(pos<m) return get()->set(l,r,pl->add(pos,ad),pr);
     44     else return get()->set(l,r,pl,pr->add(pos,ad));
     45 }
     46 inline int lowbit(int x)
     47 {    return x&-x;    }
     48 int n,m;
     49 Tree* root[MAXN];
     50 void update(int x,int pos,int ad)
     51 {
     52     for(;x<=n;x+=lowbit(x))
     53         root[x]=root[x]->add(pos,ad);
     54 }
     55 Tree* ptl[MAXN],*ptr[MAXN];
     56 int lnum,rnum;
     57 inline void get_trees(int x,int y)
     58 {
     59     lnum=rnum=0;
     60     for(;x>0;x-=lowbit(x))
     61         ptl[lnum++]=root[x];
     62     for(;y>0;y-=lowbit(y))
     63         ptr[rnum++]=root[y];
     64 }
     65 inline int get_sum()
     66 {
     67     int cnt1=0,cnt2=0;
     68     for(int i=0;i<lnum;++i) cnt1+=ptl[i]->pl->sum;
     69     for(int i=0;i<rnum;++i) cnt2+=ptr[i]->pl->sum;
     70     return cnt2-cnt1;
     71 }
     72 inline int query(int x,int y,int k)
     73 {
     74     get_trees(x-1,y);
     75     while(ptr[0]->l +1 < ptr[0]->r)
     76     {
     77         int cnt=get_sum();
     78         if(cnt<=k)
     79         {
     80             k-=cnt;
     81             for(int i=0;i<lnum;++i) ptl[i]=ptl[i]->pr;
     82             for(int i=0;i<rnum;++i) ptr[i]=ptr[i]->pr;
     83         }
     84         else
     85         {
     86             for(int i=0;i<lnum;++i) ptl[i]=ptl[i]->pl;
     87             for(int i=0;i<rnum;++i) ptr[i]=ptr[i]->pl;
     88         }
     89     }
     90     return ptr[0]->l;
     91 }
     92 struct Ask{
     93     int kind,a,b,c;
     94 }ask[MAXM];
     95 int w[MAXN],sortw[MAXN+MAXM];
     96 int main()
     97 {
     98     freopen("1.in","r",stdin);
     99     scanf("%d%d",&n,&m);
    100     int p;
    101     for(int i=0;i<n;++i)
    102         scanf("%d",w+i),sortw[i]=w[i];
    103     p=n;
    104     char cmd[5];
    105     for(int i=0;i<m;++i)
    106     {
    107         scanf("%s",cmd);
    108         if(cmd[0]=='Q')
    109         {
    110             ask[i].kind=0;
    111             scanf("%d%d%d",&ask[i].a,&ask[i].b,&ask[i].c);
    112         }
    113         else
    114         {
    115             ask[i].kind=1;
    116             scanf("%d%d",&ask[i].a,&ask[i].b);
    117             sortw[p]=ask[i].b;
    118             p++;
    119         }
    120     }
    121     std::sort(sortw,sortw+p);
    122     int nn=std::unique(sortw,sortw+p)-sortw;
    123     for(int i=0;i<n;++i) w[i]=std::lower_bound(sortw,sortw+nn,w[i])-sortw;
    124     root[0]=get()->set(0,nn,0);
    125     for(int i=1;i<=n;++i) root[i]=root[0]->add(w[i-1],1);
    126     for(int i=1;i<=n;++i) update(i+lowbit(i),w[i-1],1);
    127     for(int i=0;i<m;++i)
    128     {
    129         if(!ask[i].kind) printf("%d
    ",sortw[query(ask[i].a,ask[i].b,ask[i].c-1)]);
    130         else
    131         {
    132             int t=std::lower_bound(sortw,sortw+nn,ask[i].b)-sortw;
    133             update(ask[i].a,w[ask[i].a-1],-1);
    134             w[ask[i].a-1]=t;
    135             update(ask[i].a,t,1);
    136         }
    137     }
    138     return 0;
    139 }
    View Code
  • 相关阅读:
    在MVC3 中给HtmlHelper 添加扩展(Extension)来消除魔鬼代码
    NHibernate中使用IQueryOver时,如何添加或(OR)条件
    用@Html.EditorFor在MVC3中封装带表单(Form)提交的分页控件(通用代码)
    .NET MVC3使用CheckBox List(复选框列表)的简单方法
    Castle Windsor的MVC3的例子在最新版本(3.0Beta)上编译不过去的解决办法
    初级编程:编程巧妙注释【附图讲解】
    布同:如何循序渐进学习Python语言
    <转>:写给初学者的话《学习程序之路》
    初级编程:一层循环如何依次遍历二维数组【附代码】
    赛班S60的Python平台的源代码
  • 原文地址:https://www.cnblogs.com/lowsfish/p/4435491.html
Copyright © 2011-2022 走看看