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\n",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();
}
posted @ 2019-01-19 21:02  Lance1ot  阅读(80)  评论(0编辑  收藏