AC日记——宠物收养所 bzoj 1208

1208

思路:

  一棵splay树;

  如果来者是宠物且树空,就将其加入树中;

  如果树不空,则查找前驱后继,取最优,然后删点;

  对人亦然;

  注意边界和取模,最后的ans用long long其余用int即可;

来,上代码:

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 80005
#define mod 1000000
#define INF 0x7fffffff

struct TreeNodeType {
    int w,key,opi,size,ch[2];

    void destroy()
    {
        w=key=opi=size=ch[0]=ch[1]=0;
    }

    void create(int x)
    {
        destroy();
        key=x;
    }
};
struct TreeNodeType tree[maxn<<1];

int n,tot,flag,root;

long long ans;

inline int getson(int now)
{
    return tree[tree[now].opi].ch[1]==now;
}

inline void updata(int now)
{
    tree[now].size=tree[now].w;
    if(tree[now].ch[0]) tree[now].size+=tree[tree[now].ch[0]].size;
    if(tree[now].ch[1]) tree[now].size+=tree[tree[now].ch[1]].size;
}

inline void rotate(int now)
{
    int opi=tree[now].opi,fopi=tree[opi].opi,pos=getson(now);
    tree[opi].ch[pos]=tree[now].ch[pos^1];
    tree[tree[opi].ch[pos]].opi=opi,tree[now].opi=fopi;
    if(fopi) tree[fopi].ch[getson(opi)]=now;
    tree[opi].opi=now,tree[now].ch[pos^1]=opi;
    updata(opi),updata(now);
}

void splay(int now)
{
    for(int opi;opi=tree[now].opi;rotate(now))
    {
        if(tree[opi].opi) rotate(getson(now)==getson(opi)?opi:now);
    }
    root=now;
}

void insert(int x)
{
    if(!root) tree[++tot].create(x),root=tot;
    else
    {
        int now=root,opi=0;
        while(1)
        {
            if(tree[now].key==x)
            {
                tree[now].w++;
                tree[now].size++;
                splay(now);
                return ;
            }
            opi=now,now=tree[now].ch[x>tree[now].key];
            if(!now)
            {
                tree[++tot].create(x);
                tree[tot].opi=opi;
                tree[opi].ch[x>tree[opi].key]=tot;
                splay(tot);
                return ;
            }
        }
    }
}

inline int pre()
{
    if(tree[root].w>1) return root;
    if(!tree[root].ch[0]) return 0;
    int now=tree[root].ch[0];
    while(tree[now].ch[1]) now=tree[now].ch[1];
    return now;
}

inline int suc()
{
    if(tree[root].w>1) return root;
    if(!tree[root].ch[1]) return 0;
    int now=tree[root].ch[1];
    while(tree[now].ch[0]) now=tree[now].ch[0];
    return now;
}

void del()
{
    if(tree[root].w>1)
    {
        tree[root].w--;
        tree[root].size--;
        return ;
    }
    if(!tree[root].ch[0]&&!tree[root].ch[1])
    {
        tree[root].destroy();
        root=0;tree[root].destroy();return ;
    }
    if(tree[root].ch[0]&&!tree[root].ch[1])
    {
        int tmp=root;
        root=tree[root].ch[0];
        tree[tmp].destroy();
        tree[root].opi=0;
        return ;
    }
    if(!tree[root].ch[0]&&tree[root].ch[1])
    {
        int tmp=root;
        root=tree[root].ch[1];
        tree[tmp].destroy();
        tree[root].opi=0;
        return ;
    }
    int tmp=pre(),pos=root;
    tree[tmp].ch[1]=tree[root].ch[1];
    tree[tree[tmp].ch[1]].opi=tmp;
    root=tree[root].ch[0],tree[root].opi=0;
    tree[pos].destroy();
    splay(tree[tmp].ch[1]);
}

int main()
{
    scanf("%d",&n);int ty,x;
    while(n--)
    {
        scanf("%d%d",&ty,&x);
        if(!root)
        {
            flag=ty;
            insert(x);
        }
        else
        {
            if(ty==flag) insert(x);
            else
            {
                insert(x);
                int pr=pre(),su=suc(),to;
                if(!pr) ans+=abs(tree[su].key-x),to=su;
                else if(!su) ans+=abs(tree[pr].key-x),to=pr;
                else
                {
                    if(abs(tree[pr].key-x)<=abs(tree[su].key-x)) ans+=abs(tree[pr].key-x),to=pr;
                    else ans+=abs(tree[su].key-x),to=su;
                }
                del(),splay(to),del();
            }
        }
    }
    cout<<ans%mod;
    return 0;
}
时间: 2024-10-13 01:44:10

AC日记——宠物收养所 bzoj 1208的相关文章

AC日记——[HEOI2012]旅行问题 bzoj 2746

2746 思路: 建立ac自动机,然后把fail树抽出来: 然后在fail树上走lca(神奇): 代码: #include <cstdio> #include <vector> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 1000005 #define mod 1000000007LL struct Tr

AC日记——[Scoi2010]序列操作 bzoj 1858

1858 思路: 恶心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 struct TreeNodeType { int l,r,l1,r1,m1,l0,r0,m0,mid,size,cnt1,cnt0; bool f1,f0,ff; inline void turn(){swap(l1,l0),swap(r1,r0),swap(m1,m0),swap(cnt1,cnt0);} inline voi

AC日记——[HNOI2008]GT考试 bzoj 1009

1009 思路: KMP上走DP(矩阵加速): DP[i][j]表示当前在第i位,同是匹配到不吉利串的第j位的方案数: 代码: #include <bits/stdc++.h> using namespace std; int mod; struct MatrixType { int n,m,ai[40][40]; void mem(int n_,int m_) { n=n_,m=m_; for(int i=0;i<=n;i++) { for(int v=0;v<=m;v++) a

AC日记——魔法少女LJJ bzoj 4399

魔法少女LJJ 思路: 动态开点权值线段树+启发式合并: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 400005 #define maxm 7000000 int ch[maxm][2],X,dis[maxm],tot,

AC日记——[HNOI2007]紧急疏散evacuate bzoj 1189

[HNOI2007]紧急疏散evacuate 思路: 处理每个人到门的最短路: 然后二分答案: s向人连边流量1: 人向门拆分后的点连边流量1(拆成400,前一个点连当前点流量INF): 然后门向t连边流量二分的答案: 如果最后流量等于人的个数,则true: 来,上代码: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorit

AC日记——[NOI2006]最大获利 bzoj 1497

1497 思路: 最小割: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 55005 #define maxm 1005005 #define INF 0x7fffffff int deep[maxn],que[maxm],F[maxm],cnt=1; int n,m,

AC日记——[SCOI2010]幸运数字 bzoj 1853

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 2405  Solved: 887[Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,

AC日记——[JSOI2007]建筑抢修 bzoj 1029

1029 思路: 贪心,而且,stl水过: 然而神特么输出que.size()就错! 代码: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 150005 #define ll long long struct BuildingType {

AC日记——Mato的文件管理 bzoj 3289

3289 思路: 莫队求区间逆序对个数,树状数组维护: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 50005 int bel[maxn],blo; struct QueryType { int l,r,id; bool operator<(const QueryType pos)const { if(bel[l]==bel[pos.l]) return r<pos.r; return bel[l]&