• 【BZOJ 1901】Zju2112 Dynamic Rankings &&【COGS 257】动态排名系统 树状数组套线段树


    外面是树状数组,里面是动态开点线段树,对于查询我们先把有关点找出来,然后一起在线段树上行走,这样就是单个O(log2)的了

    #include <cstdio>
    #include <vector>
    #include <cstring>
    #define R register
    #define Inf 1000000000
    #define MAXN 50000
    using namespace std;
    inline int read()
    {
      R int sum=0;
      R char ch=getchar();
      while(ch<'0'||ch>'9')ch=getchar();
      while(ch>='0'&&ch<='9')
      {
        sum=(sum<<1)+(sum<<3)+ch-'0';
        ch=getchar();
      }
      return sum;
    }
    struct Seg_Tree
    {
      Seg_Tree *ch[2];
      int l,r,size;
      void pushup()
      {
        size=ch[0]->size+ch[1]->size;
      }
    }*null,*root[MAXN+10];
    typedef vector<Seg_Tree*> S;
    char s[1];
    int a[MAXN+10];
    inline Seg_Tree *New(int l,int r)
    {
      Seg_Tree *p=new Seg_Tree;
      p->l=l,p->r=r,p->size=0;
      p->ch[0]=p->ch[1]=null;
      return p;
    }
    int n,m;
    void ins(Seg_Tree *p,int key)
    {
      if(p->l==p->r)
      {
        p->size++;
        return;
      }
      if(key<=((p->l+p->r)>>1))
      {
        if(p->ch[0]==null)p->ch[0]=New(p->l,((p->l+p->r)>>1));
        ins(p->ch[0],key);
      }
      else
      {
        if(p->ch[1]==null)p->ch[1]=New(((p->l+p->r)>>1)+1,p->r);
        ins(p->ch[1],key);
      }
      p->pushup();
    }
    inline void Ins(int pos,int key)
    {
      while(pos<=n)
      {
        if(root[pos]==null)root[pos]=New(0,Inf);
        ins(root[pos],key);
        pos+=pos&(-pos);
      }
    }
    void del(Seg_Tree *&p,int key)
    {
      if(p->l==p->r)
      {
        p->size--;
        if(p->size==0){ delete p; p=null; }
        return;
      }
      if(key<=((p->l+p->r)>>1))del(p->ch[0],key);
      else del(p->ch[1],key);
      p->pushup();
      if(p->size==0){ delete p; p=null; }
    }
    inline void Del(int pos,int key)
    {
      while(pos<=n)
      {
        del(root[pos],key);
        pos+=pos&(-pos);
      }
    }
    inline void Init()
    {
      null=New(0,0),n=read(),m=read();
      null->ch[0]=null->ch[1]=null;
      for(R int i=1;i<=n;i++)root[i]=null;
      for(R int i=1;i<=n;i++)
        a[i]=read(),Ins(i,a[i]);
    }
    inline S Catch(int pos)
    {
      S v;v.clear();
      while(pos)
      {
        v.push_back(root[pos]);
        pos-=pos&(-pos);
      }
      return v;
    }
    inline S get_ch0(S v)
    {
      for(R int i=0;i<v.size();++i)v[i]=v[i]->ch[0];
      return v; 
    }
    inline S get_ch1(S v)
    {
      for(R int i=0;i<v.size();++i)v[i]=v[i]->ch[1];
      return v; 
    }
    int query(S v1,S v2,int k,int z,int y)
    {
      if(z==y)return z;
      R int sum=0;
      for(int i=0;i<v2.size();i++)sum+=v2[i]->ch[0]->size;
      for(int i=0;i<v1.size();i++)sum-=v1[i]->ch[0]->size;
      if(sum>=k) return query(get_ch0(v1),get_ch0(v2),k,z,(z+y)>>1);
      else return query(get_ch1(v1),get_ch1(v2),k-sum,((z+y)>>1)+1,y);
    }
    inline void Work()
    {
      R int x,y,z;
      while(m--)
      {
        scanf("%s",s);
        if(s[0]=='C')
        {
          x=read(),y=read();
          Del(x,a[x]),Ins(x,y);
          a[x]=y;
          continue;
        }
        else
        {
          x=read(),y=read(),z=read();
          printf("%d
    ",query(Catch(x-1),Catch(y),z,0,Inf));
        }
      }
    }
    void CL(Seg_Tree *p)
    {
      if(p==null)return;
      CL(p->ch[0]);
      CL(p->ch[1]);
      delete p;
    }
    inline void Clear()
    {
      for(int i=1;i<=n;i++)CL(root[i]),root[i]=NULL;
      delete null;null=NULL;
    }
    int main()
    {
      freopen("dynrank.in","r",stdin);
      freopen("dynrank.out","w",stdout);
      R int T=read();
      while(T--)
      {
        Init();
        Work();
        Clear();
      }
    }
  • 相关阅读:
    asp.net页面刷新后样式就发生了改变
    ASP.NET MVC 入门系列教程
    javascript打开邮箱服务器
    jquery验证邮箱
    MySQL数据库的索引类型
    JS判断浏览器
    Silverlight 3 新特性
    moss 2007 添加关键字及最佳匹配
    vs2008 常用快捷键
    Microsoft Enterprise Library 5.0正式版本已经发布
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7279195.html
Copyright © 2020-2023  润新知