zoukankan      html  css  js  c++  java
  • loj #6282. 数列分块入门 6

    #6282. 数列分块入门 6

    题目描述

    给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及单点插入,单点询问,数据随机生成。

    输入格式

    第一行输入一个数字 nnn。

    第二行输入 nnn 个数字,第 i 个数字为 aia_iai​​,以空格隔开。

    接下来输入 nnn 行询问,每行输入四个数字 optmathrm{opt}opt、lll、rrr、ccc,以空格隔开。

    若 opt=0mathrm{opt} = 0opt=0,表示在第 lll 个数字前插入数字 rrr (ccc 忽略)。

    若 opt=1mathrm{opt} = 1opt=1,表示询问 ara_rar​​ 的值(lll 和 ccc 忽略)。

    输出格式

    对于每次询问,输出一行一个数字表示答案。

    样例

    样例输入

    4
    1 2 2 3
    0 1 3 1
    1 1 4 4
    0 1 2 2
    1 1 2 4

    样例输出

    2
    3

    数据范围与提示

    对于 100% 100\%100% 的数据,1≤n≤100000,−231≤others 1 leq n leq 100000, -2^{31} leq mathrm{others}1n100000,231​​others、ans≤231−1 mathrm{ans} leq 2^{31}-1ans231​​1。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define maxn 2010
    using namespace std;
    int n,block,p,T,a[maxn][maxn],b[maxn][maxn],len[maxn];
    void reset(){
        int y=0,k=p/block,ll=0;
        if(p%block!=0)k++;
        p+=block;block=sqrt(p);
        T=0;
        for(int i=1;i<=k;i++)
            for(int j=1;j<=len[i];j++){
                y++;
                int kk=(y-1)/block+1;
                b[kk][++ll]=a[i][j];
                a[i][j]=0;
                if(ll==block)ll=0;
            }
        k=p/block;
        if(p%block!=0)k++;
        for(int i=1;i<=k;i++){
            if(i!=k||p%block==0)len[i]=block;
            else len[i]=p-block*block;
            for(int j=1;j<=len[i];j++)a[i][j]=b[i][j];
        }
    }
    int main(){
        scanf("%d",&n);p=n;block=sqrt(n);
        for(int i=1;i<=n;i++){
            int k=(i-1)/block+1;
            int x;scanf("%d",&x);
            a[k][++len[k]]=x;
        }
        T=0;
        for(int i=1;i<=n;i++){
            int op,l,r,c;
            scanf("%d%d%d%d",&op,&l,&r,&c);
            if(op==0){
                int k=0,t;
                for(t=1;t<=block;t++){
                    if(k+len[t]>=l)break;
                    k+=len[t];
                }
                len[t]++;
                for(int j=len[t];j>=l-k+1;j--)
                    a[t][j]=a[t][j-1];
                a[t][l-k]=r;
                T++;
                if(T==block)reset();
            }
            else {
                int k=0,t;
                for(t=1;t<=block;t++){
                    if(k+len[t]>=r)break;
                    k+=len[t];
                }
                printf("%d
    ",a[t][r-k]);
            }
        }
        return 0;
    }
  • 相关阅读:
    Java 知识点(转)
    List集合的clear方法
    WPF中控件TextBlock使用(简单)
    数据结构(严蔚敏、吴伟民)——读书笔记-2、 线性表及其基本运算、顺序存储结构
    微信公众号智能绑定功能实现(2014年10月24日 更新)
    多线程操作数据拷贝要加线程锁
    Oracle 静态监听注冊具体解释
    windows下solr7.9+tomcat7环境搭建
    &quot;Hello World &quot; —— 深入理解程序从编译到执行
    zoj 3822 Domination 概率dp 2014牡丹江站D题
  • 原文地址:https://www.cnblogs.com/thmyl/p/8966123.html
Copyright © 2011-2022 走看看