BZOJ3196: Tyvj 1730 二逼平衡树

#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
inline int min(int a,int b)
{return (a<b?a:b);}
inline int max(int a,int b)
{return (a>b?a:b);}
 inline int abs(int a)
{return (a<0?-a:a);}

char c;
bool flag; 
inline void read(int &a)
{
    a=0;flag=false;
    do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
    if(c=='-')c=getchar(),flag=true;
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
    if(flag)a=-a;
}
inline void print(int a)
{
	if(a<0)putchar('-'),a=-a;
	if(a<10){putchar('0'+a),putchar('\n');return;}
    long long base=1;
    while(base<=a)
     base=(base<<3)+(base<<1);
    base/=10;
    while(base)putchar('0'+a/base),a%=base,base/=10; 
    putchar('\n');
} 
struct Node
{
    Node *f,*lc,*rc;
    int data,rank,size;
   inline bool l(){return this->f->lc==this;}
};
Node *sta=new Node[1000001];
int cc;
int max_Con=1000000;
Node *stack[1000001];
inline Node* Node_Stackpop()
{
	return stack[cc--];
}
inline void Node_Stackpush(Node *a)
{stack[++cc]=a;}
Node *empty;
inline void begin(){empty=new Node;empty->f=empty;empty->lc=empty->rc=empty;empty->data=empty->size=empty->rank=0;cc=max_Con;for(int i=0;i<=max_Con;i++)stack[i]=sta+i;}

inline Node *New_Node(){Node *tp=Node_Stackpop();tp->lc=tp->rc=empty;tp->size=1;tp->rank=1;return tp;}
inline void up_data(Node *a)
{a->rank=a->lc->size+1;a->size=a->lc->size+a->rc->size+1;}
inline void lc_change(Node *a)
{
    if(a->f==a)
       return ;
    Node *newf;
    if(a->f->f==a->f)
       newf=a;
    else if(a->f->l())
       a->f->f->lc=a,newf=a->f->f;
    else
       a->f->f->rc=a,newf=a->f->f;
    a->rc->f=a->f;
    a->f->lc=a->rc;
    a->rc=a->f;
    a->f->f=a;
    a->f=newf;
    up_data(a->rc);
    up_data(a);
}
inline void rc_change(Node *a)
{
    if(a->f==a)
       return ;
    Node *newf;
    if(a->f->f==a->f)
       newf=a;
    else if(a->f->l())
       a->f->f->lc=a,newf=a->f->f;
    else
       a->f->f->rc=a,newf=a->f->f;
    a->lc->f=a->f;
    a->f->rc=a->lc;
    a->lc=a->f;
    a->f->f=a;
    a->f=newf;
    up_data(a->lc);
    up_data(a);
}
inline void Change(Node *a)
{a->l()?lc_change(a):rc_change(a);}
inline void Twice_Change(Node *a)
{if(a->l()==a->f->l())Change(a->f);else Change(a);Change(a);}
inline void Spaly(Node *a)
{while(a->f->f!=a->f)Twice_Change(a);while(a->f!=a)Change(a);}
inline void insert(Node *a,Node *data)
{
    if(a->data>=data->data)
       if(a->lc==empty)
          a->lc=data,data->f=a,Spaly(data);
        else insert(a->lc,data);
    else if(a->rc==empty)
        a->rc=data,data->f=a,Spaly(data);
        else insert(a->rc,data);
}
const
  int INF=100000000;
int Find_Rank(Node *a,int data)
{
      if(a->data>data)
       if(a->lc==empty)
           return 1;
       else return Find_Rank(a->lc,data);
     else if(a->data==data)
         if(a->lc!=empty)
          return min(a->rank,Find_Rank(a->lc,data));   
         else return a->rank;
     else if(a->rc==empty)
           return a->rank+1;
     else return Find_Rank(a->rc,data)+a->rank;
}
int Pre(Node *a,int data)
{
      if(a->data>=data)
       if(a->lc==empty)
           return -INF;
       else return Pre(a->lc,data);
     else if(a->rc==empty)
           return a->data;
     else return max(a->data,Pre(a->rc,data));
}
bool Has(Node *a,int data)
{
    if(a->data==data)return true;
      if(a->data>data)
       if(a->lc==empty)
           return false;
       else return Has(a->lc,data);
     else if(a->rc==empty)
           return false;
     else return Has(a->rc,data);
}
int Aft(Node *a,int data)
{
      if(a->data>data)
       if(a->lc==empty)
           return a->data;
       else return min(a->data,Aft(a->lc,data));
     else if(a->rc==empty)
           return INF;
     else return Aft(a->rc,data);
}
int Find_Data(Node *a,int rank)
{
    if(a->rank==rank) 
        return a->data;
    else if(a->rank>rank)
       return Find_Data(a->lc,rank);
    return Find_Data(a->rc,rank-a->rank);
}
struct Segement_Node
{
   Node *root;
   int l,r;
}Segement_Tree[1000001];
int data[1000001];
inline void Delete(Node *a,int Sege_place)
{
    Node *first;
    if(a==Segement_Tree[Sege_place].root)
       if(a->lc!=empty)
          Segement_Tree[Sege_place].root=a->lc;
        else
          Segement_Tree[Sege_place].root=a->rc;
    else;
    while(a->lc!=empty||a->rc!=empty)
     if(a->lc!=empty)
      Change(a->lc);
    else Change(a->rc);
    (a->l()?a->f->lc:a->f->rc)=empty;
    up_data(a->f);
    Spaly(a->f);
    Segement_Tree[Sege_place].root=a->f; 
    Node_Stackpush(a);
}
void era(Node *a,int data,int Sege_place)
{
   if(a->data==data)
        Delete(a,Sege_place);
   else if(a->data<data)
       era(a->rc,data,Sege_place),up_data(a);
   else if(a->data>data)
       era(a->lc,data,Sege_place),up_data(a);
}
 
void Build_Segement_Tree(int place,int l,int r)
{
    Segement_Tree[place].l=l;
    Segement_Tree[place].r=r;
    Segement_Tree[place].root=New_Node();
    Segement_Tree[place].root->f=Segement_Tree[place].root;
    Segement_Tree[place].root->data=data[l];
    int i;
    Node *tp=Segement_Tree[place].root;
    for(i=l+1;i<=r;i++)
    tp=New_Node(),tp->data=data[i],insert(Segement_Tree[place].root,tp),
    Segement_Tree[place].root=tp;
    if(l^r)
       Build_Segement_Tree(place<<1,l,(l+r)>>1),Build_Segement_Tree(place<<1|1,1+((l+r)>>1),r);
}
int Change_Segement_Tree(int place,int l,int data)
{
    int del_data;
    if(Segement_Tree[place].l^Segement_Tree[place].r) 
       {
       if(Segement_Tree[place<<1].r>=l)
          del_data=Change_Segement_Tree(place<<1,l,data);
       else
         del_data=Change_Segement_Tree(place<<1|1,l,data);
       era(Segement_Tree[place].root,del_data,place);
       Node *tp=New_Node();
       tp->data=data;
       insert(Segement_Tree[place].root,tp),
       Segement_Tree[place].root=tp;
       return del_data;
      }
    else
     {
        del_data=Segement_Tree[place].root->data;
        Segement_Tree[place].root->data=data;
        return del_data;
     }
}
bool Segement_Has(int place,int l,int r,int data)
{
 
    if(l<=Segement_Tree[place].l&&Segement_Tree[place].r<=r)
       return Has(Segement_Tree[place].root,data);
    int re=0;
    if(Segement_Tree[place<<1].r>=l)
       re=Segement_Has(place<<1,l,r,data);
    if(re)return true;
    if(Segement_Tree[place<<1|1].l<=r)
       re=Segement_Has(place<<1|1,l,r,data);
    return re;
}
int Segement_Rank(int place,int l,int r,int data)
{
    if(l<=Segement_Tree[place].l&&Segement_Tree[place].r<=r)
       return Find_Rank(Segement_Tree[place].root,data);
    int re=0;
    if(Segement_Tree[place<<1].r>=l)
       re+=Segement_Rank(place<<1,l,r,data)-1;
    if(Segement_Tree[place<<1|1].l<=r)
       re+=Segement_Rank(place<<1|1,l,r,data)-1;
    return re+1;
}
 
int Segement_Rank2(int place,int l,int r,int data)
{
    if(l<=Segement_Tree[place].l&&Segement_Tree[place].r<=r)
       return Find_Rank(Segement_Tree[place].root,data);
    int re=0;
    if(Segement_Tree[place<<1].r>=l)
       re+=Segement_Rank2(place<<1,l,r,data)-1;
    if(Segement_Tree[place<<1|1].l<=r)
       re+=Segement_Rank2(place<<1|1,l,r,data)-1;
    return re+1;
}
 
int Segement_Pre(int place,int l,int r,int data)
{
    if(l<=Segement_Tree[place].l&&Segement_Tree[place].r<=r)
       return Pre(Segement_Tree[place].root,data);
   int re=-INF;
    if(Segement_Tree[place<<1].r>=l)
       re=Segement_Pre(place<<1,l,r,data);
    if(Segement_Tree[place<<1|1].l<=r)
       re=max(re,Segement_Pre(place<<1|1,l,r,data));
    return re;
}
int Segement_Aft(int place,int l,int r,int data)
{
    if(l<=Segement_Tree[place].l&&Segement_Tree[place].r<=r)
       return Aft(Segement_Tree[place].root,data);
   int re=INF;
    if(Segement_Tree[place<<1].r>=l)
       re=Segement_Aft(place<<1,l,r,data);
    if(Segement_Tree[place<<1|1].l<=r)
       re=min(re,Segement_Aft(place<<1|1,l,r,data));
    return re;
}
 
inline int Divid(int k,int l,int r)
{
    int data,li=k,ri=Segement_Tree[1].root->size;
    int  mid,cp;
     while(li<(ri-1))
     {
        mid=(li+ri)>>1;
        data=Find_Data(Segement_Tree[1].root,mid);
        if(Segement_Rank2(1,l,r,data)<=k)
           li=mid;
        else
           ri=mid-1;
    }     
    data=Find_Data(Segement_Tree[1].root,li);
    if(Segement_Has(1,l,r,data)&&Segement_Rank2(1,l,r,Find_Data(Segement_Tree[1].root,ri))!=k)
       return data;
    else
       return    Find_Data(Segement_Tree[1].root,ri);
         
}
int main()
{
    int i,n,m,j,k,l;
    read(n),read(m);
    for(i=1;i<=n;i++)   read(data[i]);
    begin();
    int data;
    Build_Segement_Tree(1,1,n);
    for(i=1;i<=m;i++)
       {
         read(j);
         if(j==1)
            {
                read(k),read(l),read(data);
                print(Segement_Rank(1,k,l,data));
            }
        else if(j==2)
            {
                read(j),read(k),read(l);
               print(Divid(l,j,k));
            }
        else if(j==3)
             {
                read(j),read(k);
                Change_Segement_Tree(1,j,k);
             }
        else if(j==4)
             {
                read(j),read(k),read(l);
                print(Segement_Pre(1,j,k,l));
             }
        else if(j==5)
             {
                read(j),read(k),read(l);
                print(Segement_Aft(1,j,k,l));
			 }
       }
    return 0;
} 

人生第一道树套树。。。

反正就是线段树套平衡树。。。不过听Claris说把外层换成权值线段树然后用内部平衡树维护区间可以少一个log。。。Orz反正我是不会

一开始一直RE然后才发现是自己脑残New Node的时候没有返回tp的地址 windows上居然可以过去  误

不管怎么说  还是自己太弱了QAQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值