码迷,mamicode.com
首页 > 其他好文 > 详细

noipd2t3列队

时间:2017-12-07 20:56:40      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:部分   val   操作   ios   nod   scan   open   mat   closed   

吉老师的题还真是难呢...

正解至今不会,只会平衡树的做法

这种用平衡树上一个点表示一段区间的题还真要做做...想起来挺难受的

建n棵平衡树表示每行的m-1个元素

再建一棵平衡树维护最后一列

中间要支持一个split操作,就是把[l,r]分成[l,x-1],x,[x+1,r]三部分,很好做

相比于bzoj上的诸多神题,这题细节不多,写起来轻松加愉快

这题要tmd动态开节点!!!具体在代码中的DynaOpen函数中

还是Naive啊,noip前刚学完平衡树,考场上竟然不会做

这回也算是填了坑吧

Sylvia一点都不可爱

技术分享图片
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#define ll long long
#include<queue>
using namespace std;
const int maxn=3e6+233;
#define l(x) son[x][0]
#define r(x) son[x][1]
int Size;
int son[maxn][2],fa[maxn];
ll size[maxn],lef[maxn],rig[maxn];
struct SplayTree
{
    int rt;
    inline void pushup(int id){size[id]=size[l(id)]+size[r(id)]+1+rig[id]-lef[id];}
    inline void rotate(int x,int &k)
    {
        int y=fa[x],z=fa[y],L,R;
        L=(r(y)==x);R=L^1;
        if(y==k)k=x;
        else son[z][son[z][1]==y]=x;
        fa[son[x][R]]=y;fa[y]=x;fa[x]=z;
        son[y][L]=son[x][R];son[x][R]=y;
        pushup(y);pushup(x);
    }
    inline void Splay(int x,int &k)
    {
        while(x!=k)
        {
            int y=fa[x],z=fa[y];
            if(y!=k)
            {
                if(son[y][0]==x^son[z][0]==y)rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
        pushup(x);
    }
    inline int getpos()
    {
        int x=rt;
        for(;son[x][1];x=son[x][1]);
        return x;
    }
    inline int addnode(ll L,ll R)
    {
        lef[++Size]=L;rig[Size]=R;size[Size]=R-L+1;
        return Size;
    }
    inline void addval(ll v)
    {
        int now=addnode(v,v);
        int pos=getpos();
        son[pos][1]=now;fa[now]=pos;
        Splay(now,rt);
    }
    inline int getpre(int x)
    {
        int now=son[x][0];
        for(;son[now][1];now=son[now][1]);
        return now;
    }
    inline int getnex(int x)
    {
        int now=son[x][1];
        for(;son[now][0];now=son[now][0]);
        return now;
    }
    inline ll split(int now,ll k)
    {
        Splay(now,rt);
        k=k+lef[now]-1;
        int tmp=addnode(k+1,rig[now]);
        rig[now]=k-1;
        if(!son[now][1])
        {
            son[now][1]=tmp;
            fa[tmp]=now;
        }
        else
        {
            int pos=getnex(now);
            son[pos][0]=tmp;fa[tmp]=pos;
            Splay(tmp,rt);
        }
        return k;
    }
    inline ll query(ll x)
    {
        int now=rt;ll len;
        while(1)
        {
            if(x<=size[son[now][0]])now=son[now][0];
            else
            {
                x-=size[son[now][0]];
                len=rig[now]-lef[now]+1;
                if(x<=len)
                {
                    if(x==1)
                     {
                        ll res=lef[now];
                        lef[now]++;
                        Splay(now,rt);
                        pushup(now);
                        return res;
                     }
                     if(x==len)
                     {
                        ll res=rig[now];
                        rig[now]--;
                        Splay(now,rt);
                        pushup(now);
                        return res;
                     }
                     else return split(now,x);
                }
                x=x-(rig[now]-lef[now]+1);
                now=son[now][1];
            }
        }
    }
    inline void init(ll L,ll R){rt=addnode(L,R);}
}Phalanx[maxn];
ll n,m,q;
void DynaOpen()
{
    for(int i=1;i<=n;i++)Phalanx[i].init(m*(i-1)+1,i*m-1);
    Phalanx[0].init(m,m);
    for(int i=2;i<=n;i++)Phalanx[0].addval(i*m);
}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&q);
    DynaOpen();
    int x,y;ll va;
    while(q--)
    {
        scanf("%d%d",&x,&y);
        if(y==m)
        {
            printf("%lld\n",va=Phalanx[0].query(x));
            Phalanx[0].addval(va);
        }
        else
        {
            printf("%lld\n",va=Phalanx[x].query(y));
            Phalanx[x].addval(Phalanx[0].query(x));
            Phalanx[0].addval(va);
        }
    }
}
View Code

 

noipd2t3列队

标签:部分   val   操作   ios   nod   scan   open   mat   closed   

原文地址:http://www.cnblogs.com/Kong-Ruo/p/8000572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!