首页 > 其他分享 >数列分块入门

数列分块入门

时间:2023-07-04 17:15:06浏览次数:42  
标签:return 入门 分块 int register pos long MAXN 数列

1. 数列分块入门1

区间修改,单点查询

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=5e4+5;
int n,len,cnt;
int a[MAXN],tag[MAXN];
int pos[MAXN],l[MAXN],r[MAXN];
inline void add(int x,int y,int k)
{
    if(x>y)return;
    if(pos[x]==pos[y])
    {
        for(register int i=x;i<=y;i++)
            a[i]+=k;
        return;
    }
    for(register int i=x;i<=r[pos[x]];i++)a[i]+=k;
    for(register int i=l[pos[y]];i<=y;i++)a[i]+=k;
    for(register int i=pos[x]+1;i<=pos[y]-1;i++)tag[i]+=k;
}
signed main()
{
    scanf("%lld",&n);
    len=sqrt(n);
    cnt=n/len+(n%len!=0);
    for(register int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        pos[i]=(i-1)/len+1;
    }
    for(register int i=1;i<=cnt;i++)
    {
        l[i]=(i-1)*len+1;
        r[i]=i*len;
    }
    for(register int i=1;i<=n;i++)
    {
        int op,x,y,c;
        scanf("%lld%lld%lld%lld",&op,&x,&y,&c);
        if(op==0)add(x,y,c);
        if(op==1)printf("%lld\n",a[y]+tag[pos[y]]);
    }
    return 0;
}

2. 数列分块入门2

区间修改,询问区间中小于 \(c\) 的数的个数

用 \(b\) 数组记录每个块排序之后的数组,以便二分查询排名

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e5+5;
int n,len,cnt;
int a[MAXN],b[MAXN],tag[MAXN];
int pos[MAXN],l[MAXN],r[MAXN];
inline void add(int x,int y,int k)
{
    if(x>y)return;
    if(pos[x]==pos[y])
    {
        for(register int i=x;i<=y;i++)
            a[i]+=k;
        return;
    }
    for(register int i=x;i<=r[pos[x]];i++)a[i]+=k;
    for(register int i=l[pos[y]];i<=y;i++)a[i]+=k;
    for(register int i=pos[x]+1;i<=pos[y]-1;i++)tag[i]+=k;
}
inline int ask(int x,int y,int k)
{
    int sum=0;
    if(x>y)return 0;
    if(pos[x]==pos[y])
    {
        for(register int i=x;i<=y;i++)
            if(a[i]+tag[pos[i]]<k)sum++;
        return sum;
    }
    for(register int i=x;i<=r[pos[x]];i++)if(a[i]+tag[pos[i]]<k)sum++;
    for(register int i=l[pos[y]];i<=y;i++)if(a[i]+tag[pos[i]]<k)sum++;
    for(register int i=pos[x]+1;i<=pos[y]-1;i++)
    {
        int w=lower_bound(b+l[i],b+1+r[i],k-tag[i])-b;
        sum+=(w-l[i]);
    }
    return sum;
}
signed main()
{
    scanf("%lld",&n);
    len=sqrt(n);
    cnt=(n/len)+(n%len!=0);
    for(register int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        b[i]=a[i];
        pos[i]=(i-1)/len+1;
    }
    for(register int i=1;i<=cnt;i++)
    {
        l[i]=(i-1)*len+1;
        r[i]=i*len;
    }
    r[cnt]=n;
    for(register int i=1;i<=cnt;i++)
        sort(b+l[i],b+1+r[i]);
    for(register int i=1;i<=n;i++)
    {
        int op,x,y,c;
        scanf("%lld%lld%lld%lld",&op,&x,&y,&c);
        if(op==0)
        {
            add(x,y,c);
            for(register int i=l[pos[x]];i<=r[pos[x]];i++)b[i]=a[i];
            for(register int i=l[pos[y]];i<=r[pos[y]];i++)b[i]=a[i];
            sort(b+l[pos[x]],b+1+r[pos[x]]);
            sort(b+l[pos[y]],b+1+r[pos[y]]);
        }
        if(op==1)printf("%lld\n",ask(x,y,c*c));
    }
    return 0;
}

3. 数列分块入门3

区间修改,询问区间中 \(c\) 的前驱

和上一题差不多,同样也是块内排序,二分查找

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e5+5;
int n,len,cnt;
int a[MAXN],b[MAXN],tag[MAXN];
int pos[MAXN],l[MAXN],r[MAXN];
inline void add(int x,int y,int k)
{
    if(x>y)return;
    if(pos[x]==pos[y])
    {
        for(register int i=x;i<=y;i++)
            a[i]+=k;
        return;
    }
    for(register int i=x;i<=r[pos[x]];i++)a[i]+=k;
    for(register int i=l[pos[y]];i<=y;i++)a[i]+=k;
    for(register int i=pos[x]+1;i<=pos[y]-1;i++)tag[i]+=k;
}
inline int ask(int x,int y,int k)
{
    int ans=-1;
    if(x>y)return ans;
    if(pos[x]==pos[y])
    {
        for(register int i=x;i<=y;i++)
            if(a[i]+tag[pos[i]]<k)ans=max(ans,a[i]+tag[pos[i]]);
        return ans;
    }
    for(register int i=x;i<=r[pos[x]];i++)if(a[i]+tag[pos[i]]<k)ans=max(ans,a[i]+tag[pos[i]]);
    for(register int i=l[pos[y]];i<=y;i++)if(a[i]+tag[pos[i]]<k)ans=max(ans,a[i]+tag[pos[i]]);
    for(register int i=pos[x]+1;i<=pos[y]-1;i++)
    {
        int w=lower_bound(b+l[i],b+1+r[i],k-tag[i])-b;
        w--;
        if(b[w]+tag[pos[w]]<k)ans=max(ans,b[w]+tag[pos[w]]);
    }
    return ans;
}
signed main()
{
    scanf("%lld",&n);
    len=sqrt(n);
    cnt=(n/len)+(n%len!=0);
    for(register int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        b[i]=a[i];
        pos[i]=(i-1)/len+1;
    }
    for(register int i=1;i<=cnt;i++)
    {
        l[i]=(i-1)*len+1;
        r[i]=i*len;
    }
    r[cnt]=n;
    for(register int i=1;i<=cnt;i++)
        sort(b+l[i],b+1+r[i]);
    for(register int i=1;i<=n;i++)
    {
        int op,x,y,c;
        scanf("%lld%lld%lld%lld",&op,&x,&y,&c);
        if(op==0)
        {
            add(x,y,c);
            for(register int i=l[pos[x]];i<=r[pos[x]];i++)b[i]=a[i];
            for(register int i=l[pos[y]];i<=r[pos[y]];i++)b[i]=a[i];
            sort(b+l[pos[x]],b+1+r[pos[x]]);
            sort(b+l[pos[y]],b+1+r[pos[y]]);
        }
        if(op==1)printf("%lld\n",ask(x,y,c));
    }
    return 0;
}

标签:return,入门,分块,int,register,pos,long,MAXN,数列
From: https://www.cnblogs.com/yzh-error404/p/17526223.html

相关文章

  • (转)Rancher 2.6 安装部署及入门示例
    原文:https://blog.csdn.net/weixin_41636021/article/details/1279767120.Rancher2.X简介Rancher是为使用容器的公司打造的容器管理平台。Rancher简化了使用Kubernetes的流程,开发者可以随处运行Kubernetes(RunKubernetesEverywhere),满足IT需求规范,赋能DevOps团队。ra......
  • 【Netty】「萌新入门」(三)ChannelFuture 与 CloseFuture
    前言本篇博文是《从0到1学习Netty》中入门系列的第三篇博文,主要内容是介绍Netty中ChannelFuture与CloseFuture的使用,解决连接问题与关闭问题,往期系列文章请访问博主的Netty专栏,博文中的所有代码全部收集在博主的GitHub仓库中;连接问题与ChannelFuture在Netty中,所有的......
  • Element-快速入门
     <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><divid="app"><div><el-button>默认按钮......
  • rust入门(一)
    1、安装Rust无论使用何种系统,均可以根据Rust官方网站提供的rustup-init工具完成Rust的安装.rustup-init下载地址:  https://www.rust-lang.org/zh-CN/tools/install根据系统提示进行安装,安装完成后,验证是否安装成功rustc--version提示:如果你使用的是Linux......
  • kernel pwn入门
    LinuxKernel介绍Linux内核是Linux操作系统的核心组件,它提供了操作系统的基本功能和服务。它是一个开源软件,由LinusTorvalds在1991年开始开发,并得到了全球广泛的贡献和支持。Linux内核的主要功能包括进程管理、内存管理、文件系统、网络通信、设备驱动程序等。它负责管理......
  • CakePHP教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介CakePHP是一个运用了诸如ActiveRecord、AssociationDataMapping、FrontController和MVC等著名设计模式的快速开发框架。该项目主要目标是提供一个可以让各种层次的PHP开发人员快速地开发出健壮的Web应用,而又不失灵活性。CakePHP是一个基于PHP,免费且开源的迅速发展框......
  • springMVC入门
    定义Controller//定义Controller//使用@Controller定义bean@ControllerpublicclassUserController{//设置当前操作的访问路径@RequestMapping("/save")//设置当前操作的返回值类型@ResponseBodypublicStringsave(){System.out.p......
  • Python递归算法从入门到精通
    递归是一种常见且重要的算法设计和解决问题的方法。它通过将问题分解为规模更小的子问题,并通过解决子问题来解决原始问题。递归算法的关键在于找到递归终止条件和递归调用的方式。本文将介绍递归的基本原理、应用场景,并通过相关的Python代码示例详细讲解递归算法的使用。一、递归......
  • Vue-快速入门
     <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><divid="app"><inputv-model="username">......
  • js 实现斐波那契数列
    O2^N算法,常规写法,递归实现functionfib(n){if(n==0||n===1)return1;returnfib(n-1)+fib(n-2);};console.log(fib(3));//5console.log(fib(5));//8O(N)算法,动态规划,重叠子问题functionfibonacci(n){if(n<=1)returnn;......