博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1058 报表统计(splay+set)
阅读量:5929 次
发布时间:2019-06-19

本文共 2906 字,大约阅读时间需要 9 分钟。

题目链接:

题意:给出一个数列,初始时有n个数字。三种操作:(1)在第i个之后插入数字k,(1<=i<=n),注意这里的插入,这个n就是一开始的n,不是当前数列的长度。比如若在第i个之后插入数字x,又再第i个数字之后插入y,那么y要插在x的后面;(2)询问数列中相邻两项差值的最小值;(3)询问整个数列所有数中差值的最小值。

思路:(1)首先,第二种询问比较容易解决,只要将所有数字插入到set中,每次找与当前数字最近的两个比较即可;并且显然这个值只会递减不会增加;

(2)对于第一种查询我使用splay实现,节点保存当前节点的val以及以当前节点为根的子树的区间的两个端点的值Lval和Rval,以及相邻数字的最小值Min。每次更新即可。

 

struct node
{
    i64 val,Lval,Rval,Min;
    int size;
    node *p,*c[2];
};
node a[N],*nullNode,*root,*x1,*x2;
int cnt;
node *newNode(i64 val,node *p)
{
    node *e=&a[cnt++];
    e->c[0]=e->c[1]=nullNode;
    e->p=p;
    e->val=e->Lval=e->Rval=val;
    e->Min=inf;
    e->size=1;
    return e;
}
void pushUp(node *p)
{
    if(p==nullNode) return;
    p->size=1+p->c[0]->size+p->c[1]->size;
    p->Min=inf;
    if(p->c[0]!=x1&&p->c[0]!=x2&&p->c[0]!=nullNode)
    {
        p->Min=min(abs(p->val-p->c[0]->Rval),p->c[0]->Min);
        p->Lval=p->c[0]->Lval;
    }
    else p->Lval=p->val;
    if(p->c[1]!=x1&&p->c[1]!=x2&&p->c[1]!=nullNode)
    {
        p->Min=min(p->Min,min(abs(p->val-p->c[1]->Lval),p->c[1]->Min));
        p->Rval=p->c[1]->Rval;
    }
    else p->Rval=p->val;
}
void init()
{
    cnt=0;
    nullNode=0;
    nullNode=newNode(0,nullNode);
    nullNode->size=0;
    root=newNode(inf,nullNode);
    root->c[1]=newNode(inf,root);
    pushUp(root);
    x1=root;
    x2=root->c[1];
}
void zig(node *x)
{
    node *p=x->p,*q=p->p;
    p->c[0]=x->c[1];
    if(x->c[1]!=nullNode) x->c[1]->p=p;
    x->c[1]=p;
    p->p=x;
    if(q!=nullNode)
    {
        if(q->c[0]==p) q->c[0]=x;
        else q->c[1]=x;
    }
    x->p=q;
    pushUp(p);
    pushUp(x);
    if(root==p) root=x;
}
void zag(node *x)
{
    node *p=x->p,*q=p->p;
    p->c[1]=x->c[0];
    if(x->c[0]!=nullNode) x->c[0]->p=p;
    x->c[0]=p;
    p->p=x;
    if(q!=nullNode)
    {
        if(q->c[0]==p) q->c[0]=x;
        else q->c[1]=x;
    }
    x->p=q;
    pushUp(p);
    pushUp(x);
    if(root==p) root=x;
}
void splay(node *x,node *goal)
{
    while(x->p!=goal)
    {
        if(x->p->p!=goal)
        {
            if(x->p->p->c[0]==x->p)
            {
                if(x->p->c[0]==x) zig(x->p),zig(x);
                else zag(x),zig(x);
            }
            else
            {
                if(x->p->c[1]==x) zag(x->p),zag(x);
                else zig(x),zag(x);
            }
        }
        else
        {
            if(x->p->c[0]==x) zig(x);
            else zag(x);
        }
    }
}
void select(int k,node *goal)
{
    node *x=root;
    while(k!=1+x->c[0]->size)
    {
        if(k<=x->c[0]->size) x=x->c[0];
        else
        {
            k-=1+x->c[0]->size;
            x=x->c[1];
        }
    }
    splay(x,goal);
}
i64 ans1,ans2;
set<i64> s;
void insert(int k,i64 val)
{
    select(k+1,nullNode);
    select(k+2,root);
    node *p=newNode(val,root->c[1]);
    root->c[1]->c[0]=p;
    splay(root->c[1]->c[0],nullNode);
    ans1=root->Min;
    if(ans2==0) return;
    set<i64>::iterator it;
    it=s.lower_bound(val);
    if(it!=s.end())
    {
        if(abs(*it-val)<ans2) ans2=abs(*it-val);
    }
    if(it!=s.begin())
    {
        it--;
        if(abs(*it-val)<ans2) ans2=abs(*it-val);
    }
    s.insert(val);
}
int n,m;
int S[N];
void add(int x)
{
    while(x<N)
    {
        S[x]++;
        x+=x&-x;
    }
}
int get(int x)
{
    int ans=0;
    while(x)
    {
        ans+=S[x];
        x-=x&-x;
    }
    return ans;
}
int main()
{
    init(); RD(n,m); ans1=ans2=inf;
    int i;
    i64 x;
    FOR1(i,n)
    {
        RD(x);
        insert(get(i),x);
        add(i);
    }
    char op[20];
    int pos;
    i64 val;
    while(m--)
    {
        RD(op);
        if(op[0]=='I')
        {
            RD(pos);
            RD(val);
            insert(get(pos),val);
            add(pos);
        }
        else if(op[4]=='G') PR(ans1);
        else PR(ans2);
    }
    return 0;
}

转载地址:http://sqktx.baihongyu.com/

你可能感兴趣的文章
dependencies 和 devDependencies 的异同
查看>>
弹幕,是怎样练成的?
查看>>
扁平数组和树形结构的相互转换
查看>>
FIBOS 发布了服务于区块链项目落地的稳定币——FOD
查看>>
提高 JavaScript 开发效率的高级 VSCode 扩展!
查看>>
深入浅出Node.js - 异步编程
查看>>
不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧
查看>>
CreateJS神坑之旅
查看>>
SQLServer之删除视图
查看>>
[LeetCode] 171. Excel Sheet Column Number
查看>>
SAP成都研究院DevOps那些事
查看>>
基于drone的CI/CD,对接kubernetes,见证灵活与自由,CI/CD对接kubernetes
查看>>
webpack4配置之分享几个常用插件
查看>>
【面试】Java基础的那些事-Thr
查看>>
MySQL JSON数据类型操作
查看>>
JS组件开发之面向对象及物理模型编程
查看>>
SpringBoot非官方教程 | 第四篇:SpringBoot 整合JPA
查看>>
[ng-alain系列]目录结构与版本升级说明
查看>>
职责链模式
查看>>
动态数据源@四种实现方案对比
查看>>