• Loj_6282. 数列分块入门 6


    Loj_6282

    这个题目涉及到了块的重构,这里使用了(sqrt{n})次插入便重构的方法

    讲重复的操作提出来做了函数

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    
    const int maxn=101000;
    const int inf=0x7fffffff;
    
    struct Point
    {
        int l;
        int r;
        int val;
    };
    
    struct Square
    {
        int begin;
        int size;
    };
    
    Point base[maxn<<1];
    Square squ[maxn>>2];
    int tail,size,belong[maxn<<1];
    int n,sum;
    
    void input()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&base[i].val);
            base[i].l=i-1;
            base[i].r=i+1;
        }
        base[0].r=1;base[0].l=n;//0号位置是开头
        base[n].r=inf;//inf是链表结束标志
        sum=n+1;tail=n;//加一
        return ;
    }//输入
    
    void init()
    {
        size=floor(sqrt(sum));
        int now=size,Belong=0;
        for(int i=0;i!=inf;i=base[i].r)
        {
            ++now;
            if(now==size+1)//达到了块的个数
            {
                now=1,++Belong;//下一个块
                squ[Belong].begin=i;
                squ[Belong].size=0;
            }
            belong[i]=Belong;
            ++squ[Belong].size;
        }
        return ;
    }
    
    void insert(int l,int r,int val)//在l,r中插入val
    {
        ++squ[belong[l]].size;
        base[++tail].val=val;
        base[tail].l=l;
        base[tail].r=r;
        base[l].r=tail;
        base[r].l=tail;
        belong[tail]=belong[l];//从属于前一个块
        return ;
    }
    
    int contain(int &pos)//返回从左往右数第pos个元素在哪一个块里,然后利用引用,讲pos变为在块中的第几个元素
    {
        int res=1;
        while(pos>squ[res].size)    pos-=squ[res++].size;
        return res;
    }
    
    int position(int K,int pos)//第k个块的第pos个元素
    {
        int res=squ[K].begin,i=1;
        while(i<pos)
        {
            res=base[res].r;
            i++;
        }
        return res;//返回标号
    }
    
    void Insert(int pos,int val)
    {
        int from=contain(pos);
        int which=position(from,pos);
        insert(base[which].l,which,val);
        return ;
    }
    
    void Ask(int pos)
    {
        int from=contain(pos);
        int which=position(from,pos);
        printf("%d
    ",base[which].val);
        return ;
    }
    
    void solve()
    {
        int a,b,c,d,T=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(a==0)    Insert(b+1,c),++T,++sum;
            else    Ask(c+1);
            if(T==size) init(),T=0;
        }
        return ;
    }
    
    int main()
    {
        input();
        init();
        solve();
    }
    
  • 相关阅读:
    BZOJ1299 [LLH邀请赛]巧克力棒
    BZOJ1046 [HAOI2007]上升序列
    BZOJ1798 [Ahoi2009]Seq 维护序列seq
    BZOJ2045 双亲数
    BZOJ2301 [HAOI2011]Problem b
    BZOJ1021 [SHOI2008]Debt 循环的债务
    BZOJ2618 [Cqoi2006]凸多边形
    BZOJ1069 [SCOI2007]最大土地面积
    BZOJ1051 [HAOI2006]受欢迎的牛
    2017年09月23日普级组 环
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/10293248.html
Copyright © 2020-2023  润新知