洛谷P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II(离线区间逆序对+莫队二次离线)

news2025/1/16 3:46:32

题目

给你一个长为n(1<=n<=1e5)的序列a(0<=ai<=1e9),

m(1<=m<=1e5)次询问,每次查询一个区间[l,r]的逆序对数,可离线。

思路来源

登录 - 洛谷

三道经典分块题的更优复杂度解法&[Ynoi2019模拟赛]题解 - 博客 - OldDriverTree的博客

值域分块入门__ChiFAN_的博客-CSDN博客

题解

莫队二次离线:

1. 普通的莫队求区间逆序对个数,是莫队+树状数组求逆序对,复杂度O(n\sqrt[]{n}logn)

插入/删除一个值v时,实际要求当前区间[l,r]内,比v大/小的数的个数①,用树状数组求

而①可以继续离线,转化为求[1,r]比v大/小的数的个数-[1,l-1]比v大/小的数的个数

共有O(n\sqrt[]{n})个莫队询问,O(n)个前缀离线修改,

所以,需要一个O(\sqrt[]{n})的插入,O(1)的查询的数据结构,这就是值域分块

a[i]表示i位置的值,普通的莫队/分块都是按i分块,也就是按位置分块

而值域分块:按值的出现次数分块

cnt[i]:i这个值出现的次数,每\sqrt[]{n}个出现次数分一块,

这样就能实现O(\sqrt[]{n})的插入,O(1)的查询了

维护块内的个数的前缀和/后缀和,块间的个数的前缀和/后缀和,

插入时修改O(\sqrt[]{n})个块+块内位置,查询O(1)查

复杂度O(n\sqrt[]{n}+q\sqrt[]{n})

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=100005;
int n,m;ll a[N];
inline int lowbit(int x){return x&-x;}
ll c[N],sz=0;
int p[N];bool cmp(int x,int y){return a[x]<a[y];}
inline void add(int x,ll k){sz+=k;for(;x<=n;x+=lowbit(x))c[x]+=k;}
inline ll getsum(int x){ll ans=0;for(;x;x-=lowbit(x))ans+=c[x];return ans;}
ll L[N],R[N];//L[i]:1~i-1有多少个数大于a[i];R[i]:i+1~n有多少个数小于a[i] 

const int block=310;
struct ASK
{
    int l,r,p;
}ask[N];
inline bool mmp(ASK n1,ASK n2)
{
    if(n1.l/block!=n2.l/block)return n1.l<n2.l;
    if((n1.l/block)&1)return n2.r<n1.r;
    return n1.r<n2.r;
}
struct node{int l,r,p,op;};
vector<node>ls[N],rs[N];
int B,bl[N/block+5],br[N/block+5],w[N];
int s[N/block+5],C[N];

ll ret[N],ans[N];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        p[i]=i;
    }
    sort(p+1,p+n+1,cmp);
    ll tmp=a[p[1]];a[p[1]]=1;
    for(int i=2,t=1;i<=n;i++)
    {
        if(a[p[i]]!=tmp)t++;
        tmp=a[p[i]];a[p[i]]=t;
    }//离散化 

    for(int i=1;i<=n;i++)
    {
        L[i]=L[i-1]+sz-getsum(a[i]);
        add(a[i],1);//L[i]转前缀和 
    }//for(int i=1;i<=n;i++)printf("%lld ",L[i]);puts("");
    memset(c,0,sizeof(c));
    for(int i=n;i>=1;i--)
    {
        R[i]=R[i+1]+getsum(a[i]-1);
        add(a[i],1);//R[i]转后缀和 
    }//for(int i=1;i<=n;i++)printf("%lld ",R[i]);puts("");

    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&ask[i].l,&ask[i].r);
        if(ask[i].l>ask[i].r)swap(ask[i].l,ask[i].r);
        ask[i].p=i;
    }
    sort(ask+1,ask+m+1,mmp);//排序 
    ask[0]=(ASK){1,0,0};
    for(int i=1;i<=m;i++)//莫队二次离线 
    {//把莫队的移动离线下来 
        ret[i]=L[ask[i].r]-L[ask[i-1].r]+R[ask[i].l]-R[ask[i-1].l];
             if(ask[i].r>ask[i-1].r)rs[ask[i-1].l-1].push_back((node){ask[i-1].r+1,ask[i].r,i,-1});
        else if(ask[i].r<ask[i-1].r)rs[ask[i-1].l-1].push_back((node){ask[i].r+1,ask[i-1].r,i, 1});
             if(ask[i].l<ask[i-1].l)ls[ask[i  ].r+1].push_back((node){ask[i].l,ask[i-1].l-1,i,-1});
        else if(ask[i].l>ask[i-1].l)ls[ask[i  ].r+1].push_back((node){ask[i-1].l,ask[i].l-1,i, 1});
    }

    B=(n-1)/block+1;
    for(int i=1;i<=B;i++) 
    {
        bl[i]=br[i-1]+1;
        br[i]=br[i-1]+block;
    }br[B]=n;//值域分块 
    for(int i=1;i<=B;i++)for(int j=bl[i];j<=br[i];j++)w[j]=i;

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<w[a[i]];j++)s[j]++;
        for(int j=bl[w[a[i]]];j<=a[i];j++)C[j]++;
        for(int j=0;j<rs[i].size();j++)
        {
            node t=rs[i][j];
            int l=t.l,r=t.r;
            tmp=0;
            for(int k=l;k<=r;k++)tmp+=s[w[a[k]+1]]+C[a[k]+1];
            ret[t.p]+=t.op*tmp;
        }
    }
    memset(C,0,sizeof(C));
    memset(s,0,sizeof(s));
    for(int i=n;i>=1;i--)
    {
        for(int j=w[a[i]]+1;j<=B;j++)s[j]++;
        for(int j=a[i];j<=br[w[a[i]]];j++)C[j]++;
        for(int j=0;j<ls[i].size();j++)
        {
            node t=ls[i][j];
            int l=t.l,r=t.r;
            tmp=0;
            for(int k=l;k<=r;k++)tmp+=s[w[a[k]-1]]+C[a[k]-1];
            ret[t.p]+=t.op*tmp;
        }
    }

    for(int i=1;i<=m;i++)
    {
        ret[i]+=ret[i-1];//ret最终的值是差分值 
        ans[ask[i].p]=ret[i];
    }
    for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501374.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(异或相消)猫猫数字异或和

E - Red Scarf (atcoder.jp) 刚入坑写的一道题被我拉出来对比分析了 我的思路&#xff1a; 垃圾运气选手凭借直觉乱搞猜出来的&#xff0c;没有思路。 题解思路&#xff1a; 由问题陈述中XOR的定义&#xff0c;我们可以看出计算3个或更多整数的XOR可以以任意顺序进行&#…

fastjson 代码执行 (CNVD-2017-02833)

漏洞存在原因 在fastjson<1.2.24版本中&#xff0c;在解析json的过程中&#xff0c;支持使用autoType来实例化某一个具体的类&#xff0c;并调用该类的set/get方法来访问属性。而在1.24<fastjson<1.2.48版本中后增加了反序列化白名单。 漏洞复现过程如下 在vulfocu…

解读ChatGPT中的RLHF

无论是 ChatGPT 还是 GPT-4&#xff0c;它们的核心技术机制之一都是基于人类反馈的强化学习&#xff08;Reinforcement Learning from Human Feedback&#xff0c;RLHF&#xff09;。这是大型语言模型生成领域的新训练范式&#xff0c;即以强化学习方式依据人类反馈优化语言模型…

打造属于自己的私人云笔记

打造属于自己的私人云笔记 前言效果环境标题第一步 网盘部署开启webDAV协议使用 前言 现在市面上支持私有化部署的云笔记选择不多&#xff0c;而且大多数只支持mackDown语法&#xff0c;不支持word等其他文件的编辑&#xff0c;基于此需求&#xff0c;能不能有一款笔记软件&am…

盛元广通高等级生物安全实验室(P3)管理系统

近年来&#xff0c;传染性疾病频发&#xff0c;给传染病防控和生物安全带来了前所未有的挑战&#xff0c;重点构建集生物安全三级实验室&#xff0c;统一布局科技研究和科技力量&#xff0c;成为重要传染病原和生物防范基础及应用基础研究的高地&#xff0c;高等级生物安全实验…

JavaScript实现输入长方形的宽和高,输出周长和面积的代码

以下为实现输入长方形的宽和高&#xff0c;输出周长和面积的代码和运行截图 目录 前言 一、实现输入长方形的宽和高&#xff0c;输出周长和面积 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 输入数值不是要求必须输入数值的代码 1.5 运行截图 前言 1.若…

这款视频录制剪辑软件千万别错过!

案例&#xff1a;有没有录制完成之后&#xff0c;可以直接剪辑视频的软件&#xff1f; 【我的工作经常需要对电脑上的内容进行录制、剪辑。我每次都需要使用录屏工具录制完成后&#xff0c;再使用视频剪辑工具进行剪辑&#xff0c;十分麻烦。想问一下有没有软件既能录屏又能剪…

WGCNA | 不止一个组的WGCNA怎么分析嘞!?~(一)(共识网络分析-第一步-数据整理)

1写在前面 最近又是忙碌的一米&#xff0c;做不完的手术&#xff0c;收不完的病人&#xff0c;前途堪忧&#xff0c;收入更是不堪入目。&#x1f972; 把之前的WGCNA教程再补一补吧&#xff0c;之前介绍的是雌性鼠的表型数据分析&#xff0c;只有一组&#xff0c;相对简单。&am…

elk生命周期删除日志

elk版本&#xff1a;7.14 一、简介 ELK日志我们一般都是按天存储&#xff0c;例如索引名为"prodlog-2023-05-08"&#xff0c;因为日志量所占的存储是非常大的&#xff0c;我们不能一直保存&#xff0c;而是要定期清理旧的&#xff0c;这里就以保留7天日志为例。 自…

Android开发 LogDog (日志狗)V1.2.0

目录 一、简介 二、添加LogDog 1、添加仓库 2、添加依赖 三、V1.2.0 更新和新的使用方式 1、初始化和配置 2、配置的新使用 3、使用和打印更新说明 4、更新说明 一、简介 具体日志简介可以去看1.0.2版本的简介 LogDog 简介https://blog.csdn.net/Ym_quiet/article/d…

【多任务学习】Multi-task Learning 手把手编码带数据集, 一文吃透多任务学习

文章目录 前言1.多任务学习1.1 定义1.2 原理 2. 多任务学习code2.1 数据集初探2.2 预处理2.3 网络结构2.4 训练 3. 总结 前言 我们之前讲过的模型通常聚焦单个任务,比如预测图片的类别等,在训练的时候,我们会关注某一个特定指标的优化. 但是有时候,我们需要知道一个图片,从它身…

Windows远程执行进程工具psexec和wmiexec介绍

在自动化测试或者自动化工具开发中&#xff0c;通常需要向其它电脑或者服务器发送指令&#xff0c;比如Windows发送命令到Linux服务器开启某个服务进程&#xff0c;或者读取状态信息&#xff0c;我们可以使用ssh协议实现。 如果Windows主机需要发送命令到局域网内的其它Window…

第四十五章 Unity 滚动视图 (Scroll View) UI

我们介绍一下滚动条 (Scrollbar)&#xff0c;它允许用户滚动由于太大而无法完全看到的图像或其他视图。这种效果在我们网页中经常看到&#xff0c;尤其是网页内容太长的时候&#xff0c;就会在垂直方向出现滚动条。当然&#xff0c;有时候也会在水平方向出现滚动条。我们拖动滚…

WebRTC引用计数和线程

1. 什么是引用计数&#xff1a; 引用计数是计算机编程语言中的一种内存管理技术&#xff0c;是指将资源&#xff08;可以是对象、内存、或磁盘空间等等&#xff09;的被引用次数保存起来&#xff0c;当被引用次数变为零时就将其释放的过程。 使用引用计数技术可以实现自动资源…

纯HTML+CSS网页设计期末作业(海贼王主题网站——图片可换,主题可换)

纯HTMLCSS网页设计期末作业&#xff08;海贼王主题网站——图片可换&#xff0c;主题可换&#xff09; 博主&#xff1a;命运之光 专栏&#xff1a;web网页制作大作业 网页最底下有视频可以观看网页效果&#xff0c;喜欢的可以在博主主页资源里免费下载(●’◡’●)让我们一起加…

[数据库系统] 一、添加常用约束(educoder)

1.任务&#xff1a;给表添加常用的约束。 2.相关知识 在数据库的使用过程中我们经常要限制属性的取值&#xff0c;比如有些属性不能为空&#xff0c;就需要添加非空约束&#xff0c;本关要求完成常用约束的添加和定义。 目录 (1)唯一约束 (2)添加非空约束 (3)使用默认约束…

大数据|Hive和数据仓库

前文回顾&#xff1a;HBase基本工作原理 目录 &#x1f4da;数据仓库和OLAP &#x1f407;数据仓库 &#x1f955;面向主题 &#x1f955;集成的 &#x1f955;时变的 &#x1f955;非易失的 &#x1f407;OLTP&#xff08;联机事务处理&#xff09;vs OLAP&#xff08;…

织梦城市分站怎么安装织梦二级域名站群织梦制作企业分站教程

1、安装说明 一、下载织梦多城市二级域名源码; 二、上传源码到服务器;(必须支持泛解析) 三、在浏览器输入http://你的域名/install进入安装页面; 可以参考http://www.hlzcb.com/zhimengxueyuan/zhimenganzhuangshiyong/25830.html 四、输入数据库用户名密码和数据库…

公司股权转让,变更股东要了解哪些?

什么是公司股权&#xff1f; 股权即股票持有者所具有的与其拥有的股票比例相应的权益及承担一定责任的权力。股权转让是一种物权变动行为&#xff0c;股权转让后&#xff0c;股东基于股东地位而对公司所发生的权利义务关系全部同时移转于受让人&#xff0c;受让人因此成为公司…

SpringBoot的yml多环境配置3种方法

目录 方式一&#xff1a;多个yml文件 步骤一、创建多个配置文件 步骤二、applicaiton.yml中指定配置 方式二&#xff1a; 单个yml文件 方式三&#xff1a;在pom.xml中指定环境配置 步骤一、创建多个配置文件 步骤二、在application.yml中添加多环境配置属性 步骤三、在po…