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

题目

给你一个长为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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter性能分析工具使用

使用前提 flutter常用的性能分析工具&#xff0c;这些工具都集成在android studio中&#xff0c;基本能满足我们的需求了。在下面介绍的几个工具中&#xff0c;Flutter Performance和Flutter Inspector都能够直接在debug模式下使用&#xff0c;但是DevTools只能在profile模式下…

typescript:熟练掌握typescript

一、简介 TypeScript 教程 | 菜鸟教程 TypeScript (简称:TS)是JavaScript的超集 (JS有的TS 都有)。 TypeScriptType JavaScript (在JS 基础之上&#xff0c;为JS添加了类型支持)。 哔哩哔哩_教程_TypeScript 二、TypeScript为什么要为js增加类型支持&#xff1f; 背景&am…

4年外包出来,5次面试全挂....

我的情况 大概介绍一下个人情况&#xff0c;男&#xff0c;毕业于普通二本院校非计算机专业&#xff0c;18年跨专业入行测试&#xff0c;第一份工作在湖南某软件公司&#xff0c;做了接近4年的外包测试工程师&#xff0c;今年年初&#xff0c;感觉自己不能够再这样下去了&…

鲲鹏展翅 信安高飞 | 鲲鹏开发者峰会2023-麒麟信安技术论坛成功举办!

2023年5月6日-7日&#xff0c;以“创未来 享非凡”为主题的鲲鹏开发者峰会2023在东莞松山湖举办。鲲鹏产业生态繁荣&#xff0c;稳步发展&#xff0c;正在成为行业核心场景及科研领域首选&#xff0c;加速推动数字化转型。 作为鲲鹏生态重要合作伙伴&#xff0c;麒麟信安受邀举…

Notion Ai中文指令使用技巧

Notion AI 是一种智能技术&#xff0c;可以自动处理大量数据&#xff0c;并从中提取有用的信息。它能够 智能搜索&#xff1a;通过搜索文本和查询结果进行快速访问 自动归档&#xff1a;可以根据关键字和日期自动将内容归档 内容分类&#xff1a;可以根据内容的标签和内容的…

交互式数据分析和处理新方法:pandas-ai =Pandas + ChatGPT

Python Pandas是一个为Python编程提供数据操作和分析功能的开源工具包。这个库已经成为数据科学家和分析师的必备工具。它提供了一种有效的方法来管理结构化数据(Series和DataFrame)。 在人工智能领域&#xff0c;Pandas经常用于机器学习和深度学习过程的预处理步骤。Pandas通…

基于JavaWeb实现的汽车维修管理系统

【简介】 本系统基于springboot mybatis jps架构开发&#xff0c;前后端分离&#xff0c;开发环境为jdk1.8、mysql、maven。系统功能主要分为汽车维修管理、配件管理、财务管理、基础数据管理、系统维护5大模块。 【功能结构】 【技术架构】 系统架构&#xff1a;springboot …

深度学习第J6周:ResNeXt-50实战解析

目录 一、模型结构介绍 二、前期准备 三、模型 三、训练运行 3.1训练 3.2指定图片进行预测 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] &#x1f4cc; …

移动端异构运算技术 - GPU OpenCL 编程(基础篇)

一、前言 随着移动端芯片性能的不断提升&#xff0c;在移动端上实时进行计算机图形学、深度学习模型推理等计算密集型任务不再是一个奢望。在移动端设备上&#xff0c;GPU 凭借其优秀的浮点运算性能&#xff0c;以及良好的 API 兼容性&#xff0c;成为移动端异构计算中非常重要…

Echarts使用本地JSON文件加载不出图表的解决方法以及Jquery访问本地JSON文件跨域的解决方法

前言 最近需要做一个大屏展示&#xff0c;需要用原生html5cssjs来写&#xff0c;所以去学了一下echarts的使用。在使用的过程中难免碰到许多BUG&#xff0c;百度那是必不可少的&#xff0c;可是这些人写的牛头不对马嘴&#xff0c;简直是标题党一大堆&#xff0c;令我作呕&…

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

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

龙的画法图片

由龙老师画素描中国龙的方法,大概可以遵循以下步骤: 确定龙的姿态和比例:在纸上简单地画出龙的基本形状和姿态,包括身体的长度,颈部、腿和尾巴的位置和比例关系。 添加细节:在基本形状的基础上,开始添加一些细节,如龙的头部、眼睛、鼻子、嘴巴、爪子等。注意要保持姿态和比例…

UU跑腿“跑男失联”:同城即配服务赛道商业逆袭难?

五一假期&#xff0c;人们纷纷走出家门&#xff0c;要么扎堆奔向“远方”&#xff0c;要么、享受本地烟火气息。 据文化和旅游部数据中心测算&#xff0c;劳动节假期&#xff0c;全国国内旅游出游合计2.74亿人次&#xff0c;同比增长70.83%。 五一假日的郑州东站 面对人山人海…

Docker 应用部署-MySQL

一、安装MySQL 1搜索mysql镜像 docker search mysql 2拉取mysql镜像 docker pull mysql:8.0.20 3创建容器 通过下面的命令&#xff0c;创建容器并设置端口映射、目录映射 #在用户名目录下创建mysql目录用于存储mysql数据信息 mkdir /home/mysql cd /home/mysql #创建docker容…

Python图形化编程开源项目拼码狮PinMaShi

开源仓库 #项目地址 https://github.com/supercoderlee/pinmashi https://gitee.com/supercoderlee/pinmashiPinMaShi采用electron开发&#xff0c;图形化拖拽式编程有效降低编程难度&#xff0c;对Python编程的初学者非常友好&#xff1b;积木式编程加快Python程序的开发&…

微服务介绍 SpringCloud,服务拆分和远程调用,注册中心Eureka,负载均衡Ribbon,注册中心Nacos

一、微服务介绍 1.系统架构的演变 什么是微服务&#xff0c;微服务有哪些特征SpringCloud是什么SpringCloud与Dubbo的区别 1.单体架构 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。当网站流量很小时&#xff0c;单体架构非常合适 1.单体架构 优点&a…

携带数据的Ajax POST请求

前端页面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>发送ajax POST请求 看如何携带数据</title> <script type"text/javascript"> …

第8章 未执行缓存的强制清理操作导致显示异常解决方案

1 异常产生原因&#xff1a; 由于未为Role实体定义相就的缓存强制销毁器类&#xff1a;Services.Customers.Caching.RoleCacheEventConsumer,从而导致Services.Events.EventPublisher.PublishAsync<TEvent>(TEvent event)中的 consumers实例为0,如下图所示&#xff1a; 2…

Redis(连接池)

SpringBoor环境下使用redis连接池 依赖&#xff1a; <dependencies><dependency><groupId>com.yugabyte</groupId><artifactId>jedis</artifactId><version>2.9.0-yb-11</version></dependency><dependency><…

SpringBoot基础篇3(SpringBoot+Mybatis-plus案例)

环境搭建&#xff1a;配置起步依赖pom.xml和配置文件application.yml 1.创建模块时&#xff0c;勾选的依赖有springMVC和MySQL驱动 2.手动添加的依赖有&#xff1a;MyBatis-plus、Druid、lombok <dependencies><dependency><groupId>org.springframework.…