BZOJ1901: Zju2112 Dynamic Rankings

第一次外层套权值线段树

每次用splay提取区间然后在线段树上二分即可

一开始想打替罪羊 后来。。差点砸电脑
还是splay好写

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;

struct Node
{
    Node *lc,*rc,*f;
    inline bool l(){return f->lc==this;}
    int Con,Rank,Data;
}*empty;
Node     A[1000001];
Node*Cache[1200001];
int tot;
inline Node *New_Node()
{
   Node *T=Cache[tot--];T->lc=empty,T->rc=empty;T->Con=1,T->Rank=1; 
   return T;
}
inline void Del(Node*a)
{Cache[++tot]=a;}
inline void Bg()
{
    empty=new Node;
    empty->lc=empty,empty->rc=empty,
    empty->Rank=empty->Data=empty->Con=0;
    for(tot=0;tot<=1000000;tot++)Cache[tot]=A+tot;tot--;
}
inline void updata(Node*a){a->Con=(a->Rank=1+a->lc->Con)+a->rc->Con;}
inline void Lc(Node *a)
{
    Node*f;
    if(a->f->f==a->f)f=a;
    else if(a->f->l())a->f->f->lc=a,f=a->f->f;
    else a->f->f->rc=a,f=a->f->f;
    a->f->lc=a->rc;
    a->rc->f=a->f;
    a->rc=a->f;
    a->f->f=a;
    a->f=f;
    updata(a->rc),updata(a);
}
inline void Rc(Node *a)
{
    Node*f;
    if(a->f->f==a->f)f=a;
    else if(a->f->l())a->f->f->lc=a,f=a->f->f;
    else a->f->f->rc=a,f=a->f->f;
    a->f->rc=a->lc;
    a->lc->f=a->f;
    a->lc=a->f;
    a->f->f=a;
    a->f=f;
    updata(a->lc),updata(a);
}
inline void Change(Node*a){a->l()?Lc(a):Rc(a);}
inline void TwiChange(Node*a){a->l()==a->f->l()?Change(a->f):Change(a->f);Change(a);}
inline void Splay(Node *a)
{
    while(a->f->f!=a->f)TwiChange(a);
    while(a->f!=a)Change(a);
}
inline void Splay2(Node *a)
{
    while(a->f->f->f!=a->f->f)TwiChange(a);
    while(a->f->f!=a->f)Change(a);
}
Node *Pre(Node *a,int D)
{
    if(a==empty)return a;
    if(a->Data>=D)
      return Pre(a->lc,D);
    Node *R=Pre(a->rc,D);
   return R==empty?a:R;
}
Node *Aft(Node *a,int D)
{
    if(a==empty)return a;
    if(a->Data<=D)
      return Aft(a->rc,D);
    Node *R=Aft(a->lc,D);
   return R==empty?a:R;
}
const
  int INF=1<<29;
struct Seg
{
    int l,r;
    Node* Data;
    void Bg(){Node *Bg=New_Node(),*Ed=New_Node();
    Bg->Data=-1;Ed->Data=INF;Ed->f=Bg;Bg->rc=Ed;updata(Ed);updata(Bg);Bg->f=Bg;Data=Bg;}
}T[100001];
void Build(int place,int l,int r)
{
    T[place].Bg();
    T[place].l=l;
    T[place].r=r;
    if(l^r)
      {
           Build(place<<1|1,(l+r>>1)+1,r),
           Build(place<<1,l,l+r>>1);
      }
    return ;
}
int Query(int place,int l,int r)
{
    Node *B,*E;
    B=Pre(T[place].Data,l);
    E=Aft(T[place].Data,r);
    Splay(T[place].Data=B);
    Splay2(E);
    return E->Rank-1;
}
void Del(int place,int l)
{
    Node *B,*E;
    B=Pre(T[place].Data,l);
    E=Aft(T[place].Data,l);
    Splay(B);
    Splay2(E);
    if(E->lc!=empty)
    Del(E->lc);
    E->lc=empty;
    Splay(T[place].Data=E); 
}
void Add(int place,int l)
{
    Node*N;
    Node *B,*E;
    B=Pre(T[place].Data,l);
    E=Aft(T[place].Data,l);
    Splay(B);
    Splay2(E);
    N=New_Node();
    N->Data=l;
    E->lc=N;
    N->f=E;
    updata(N);
    Splay(T[place].Data=N);
}
int Query(int place,int l,int r,int k)
{
    if(T[place].l^T[place].r)
    {
         int L=Query(place<<1,l,r);
         if(L>=k)return Query(place<<1,l,r,k);
         return Query(place<<1|1,l,r,k-L);      
    }
    else
    return T[place].l;
}
void Del(int place,int l,int data)
{
    Del(place,l);
    if(T[place].l^T[place].r)   
    {
           if(T[place<<1|1].l<=data)Del(place<<1|1,l,data);
           else Del(place<<1,l,data);

    }
    return ;
}
void Add(int place,int l,int data)
{
    Add(place,l);
    if(T[place].l^T[place].r)   
    {
           if(T[place<<1|1].l<=data)Add(place<<1|1,l,data);
           else Add(place<<1,l,data);

    }
    return ;
}
char c;
inline void read(int &a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Que
{
    bool q;
    int l,r,k;
    void In(){do c=getchar();while(c!='Q'&&c!='C');q=c=='Q';read(l),read(r);if(q)read(k);}
}L[11001];
int n,M;
map<int,int>Q; 
int TT[110001];
int Data[11001];
int main()
{
    read(n),read(M);
    int m=-1;
    for(int i=1;i<=n;i++)
        read(TT[i]),m=max(m,Data[i]=TT[i]);
    for(int i=1;i<=M;i++)
    {
       L[i].In();
       if(L[i].q)TT[i+n]=m;
       else m=max(TT[i+n]=L[i].r,m);   
    }
    int T=n+M;
    Bg();
    sort(TT+1,TT+1+T);
    T=unique(TT+1,TT+1+T)-TT-1;
    for(int i=1;i<=T;i++)
            Q[TT[i]]=i; 
    Build(1,1,m=Q[m]);  
    for(int i=1;i<=n;i++)
      Data[i]=Q[Data[i]],Add(1,i,Data[i]);
    int ans;
    for(int i=1;i<=M;i++)
      if(!L[i].q)L[i].r=Q[L[i].r];
    for(int i=1;i<=M;i++)
    {
        if(L[i].q)
         {
            ans=Query(1,L[i].l,L[i].r,L[i].k);
            ans=TT[ans];
            printf("%d\n",ans);
         }  
        else
           Del(1,L[i].l,Data[L[i].l]),Add(1,L[i].l,L[i].r),Data[L[i].l]=L[i].r;
    }
    return 0;
}
发布了237 篇原创文章 · 获赞 1 · 访问量 12万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览