[NOI2022]冒泡排序

题意:
n n n个数, m m m个限制,第 i i i个限制要求在 [ L i , R i ] [L_i,R_i] [Li,Ri]的最小值为 V i V_i Vi,你要得到最小的逆序对数。
数据满足 n , m < = 1 0 6 n,m<=10^6 n,m<=106

思路:
最近感觉自己的实力厚度有点不够,所以打算多做一点oi题目,来提高实力厚度。

这道题很容易想到把限制按照V从小到大排序,然后不断给整个区间修改为 V i V_i Vi,现在设修改完以后每个点的值为 b i b_i bi
操作完就可以知道某个点会对哪一个V的限制起作用。

我们把每个点按照 b i b_i bi分类,然后考虑保留哪些 b i b_i bi,修改哪些 b i b_i bi。考虑最小的 b b b,可以发现我们肯定要选择最少点不改变,而且都要尽量靠前,这样对后面的影响最小。然后考虑从小到达枚举 b b b,因为大的会覆盖小的,大的 b b b如果被小的 b b b分开,那么大的一定是相互独立的,所以我们可以决定出要选哪一些位置。

然后就是考虑要怎么填数才能使得逆序对数 最少。然后我就想了一个不太严谨的贪心:小的b一定比大的b能够变化的空间更多,因此我们一定是先处理大的b,在用小的b去将就大的b。所以我们就先填大的,再填小的。然后我们可以发现,空的格子里面填的最优的数一定是从小到大的,否则交换能得到更优的结果。而且,加入我给某个格子填了i,那么这个最优的值一定是把左边连续的若干个变成i,而不会改变更大的最优的数的格子。

我们用一个栈来维护这个最优的数,然后用一个线段树来维护应该改变左边的哪一部分。这个线段树维护当前最优解和改成bi之后逆序对数的差值,只需要在确定某个点的之以后把左边增加1,右边减少1即可(类似)。

感觉这个题目的思路特别的绕。

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define dwn(i,x,y) for(int i=x;i>=y;i--)
#define ll long long
using namespace std;
template<typename T>inline void qr(T &x){x=0;int f=0;char s=getchar();while(!isdigit(s))f|=s=='-',s=getchar();while(isdigit(s))x=x*10+s-48,s=getchar();x=f?-x:x;
}
int cc=0,buf[31];
template<typename T>inline void qw(T x){if(x<0)putchar('-'),x=-x;do{buf[++cc]=int(x%10);x/=10;}while(x);while(cc)putchar(buf[cc--]+'0');
}
const int N=1e6+10;
struct SGT{int l,r,c,lazy;bool clr;
}t[N<<2];
#define lc p<<1
#define rc p<<1|1
#define mid (t[p].l+t[p].r)/2
void update(int p){t[p].c=max(t[lc].c,t[rc].c);
}
void pushdown(int p){if(t[p].clr){t[lc].c=t[lc].lazy=0;t[lc].clr=1;t[rc].c=t[rc].lazy=0;t[rc].clr=1;t[p].clr=0;}if(t[p].lazy){t[lc].c+=t[p].lazy;t[lc].lazy+=t[p].lazy;t[rc].c+=t[p].lazy;t[rc].lazy+=t[p].lazy;t[p].lazy=0;}
}
void build(int p,int l,int r){t[p].l=l,t[p].r=r;t[p].c=0;t[p].lazy=0;t[p].clr=0;if(l<r){build(lc,l,mid);build(rc,mid+1,r);}
}
void change(int p,int x,int y,int k){if(x<=t[p].l&&t[p].r<=y){t[p].c+=k;t[p].lazy+=k;return;}pushdown(p);if(x<=mid)change(lc,x,y,k);if(mid<y)change(rc,x,y,k);update(p);
}
void change2(int p,int x,int y){if(x<=t[p].l&&t[p].r<=y){t[p].c=t[p].lazy=0;t[p].clr=1;return;}pushdown(p);if(x<=mid)change2(lc,x,y);if(mid<y)change2(rc,x,y);update(p);
}
int query(int p){if(t[p].l==t[p].r){if(t[p].c>=0)return 0;return t[p].l;}pushdown(p);if(t[lc].c<0)return max(t[lc].r,query(rc));else return query(lc);
}
int n,m;
int cnt,s[N];
struct node{int x,y,z;node(int xx=0,int yy=0,int zz=0):x(xx),y(yy),z(zz){}
}a[N],sta[N];int tp;
vector<int>zuo[N],you[N];
int b[N];//the max num cover i
vector<int>pos[N],seg[N];//pos was valued i; segment have value i
bool used[N];
int ans[N];
int c[N];
bool cmp1(int p1,int p2){return p1<p2;
}
bool cmp2(int p1,int p2){if(a[p1].x!=a[p2].x)return a[p1].x<a[p2].x;return a[p1].y>a[p2].y;
}
void add(int x){for(;x<=n;x+=x&-x)c[x]++;
}
int calc(int x){int ret=0;for(;x;x-=x&-x)ret+=c[x];return ret;
}
int testcase;
void solve(){qr(n),qr(m);rep(i,1,n){zuo[i].clear();you[i].clear();}cnt=0;rep(i,1,m){qr(a[i].x),qr(a[i].y),qr(a[i].z);s[++cnt]=a[i].z;}sort(s+1,s+cnt+1);cnt=unique(s+1,s+cnt+1)-s-1;rep(i,1,m){a[i].z=lower_bound(s+1,s+cnt+1,a[i].z)-s;zuo[a[i].x].push_back(i);you[a[i].y].push_back(i);}multiset<int>cover;rep(i,1,cnt){pos[i].clear();seg[i].clear();}rep(i,1,m)seg[a[i].z].push_back(i);rep(i,1,n){for(int id:zuo[i])cover.insert(a[id].z);b[i]=0;if(cover.size()){b[i]=*(--cover.end());pos[b[i]].push_back(i);}for(int id:you[i])cover.erase(cover.find(a[id].z));}rep(i,1,n)used[i]=0;bool flag=1;rep(i,1,cnt){sort(pos[i].begin(),pos[i].end(),cmp1);sort(seg[i].begin(),seg[i].end(),cmp2);int now=(int)pos[i].size()-1,last=n+1;for(int j=(int)seg[i].size()-1;j>=0;j--){node t=a[seg[i][j]];if(last<=t.y)continue;while(now>0&&pos[i][now-1]>=t.x)now--;if(now<0||pos[i][now]>t.y||pos[i][now]<t.x){flag=0;break;}last=pos[i][now];used[last]=1;}if(!flag)break;}if(!flag){puts("-1");return;}build(1,1,n);sta[tp=1]=node(1,n,cnt+1);dwn(i,cnt,1){for(int x:pos[i]){if(used[x]){ans[x]=i;if(x>1)change(1,1,x-1,-1);}}int len=query(1);if(len){while(tp&&sta[tp].y<=len)tp--;if(tp){sta[tp].x=len+1;}sta[++tp]=node(1,len,i);change2(1,1,len);}for(int x:pos[i]){if(!used[x]){int l=1,r=tp,Mid,pos;while(l<=r){Mid=(l+r)/2;if(sta[Mid].x<=x)pos=Mid,r=Mid-1;else l=Mid+1;}ans[x]=sta[pos].z;if(x<n)change(1,x+1,n,1);}}for(int x:pos[i]){if(used[x]){if(x<n)change(1,x+1,n,1);}}}rep(x,1,n)if(!b[x]){int l=1,r=tp,Mid,pos;while(l<=r){Mid=(l+r)/2;if(sta[Mid].x<=x)pos=Mid,r=Mid-1;else l=Mid+1;}ans[x]=sta[pos].z;}rep(i,1,n)c[i]=0;ll tot=0;dwn(i,n,1){tot+=calc(ans[i]-1);add(ans[i]);}qw(tot);puts("");
}
int main(){// freopen("bubble6.in","r",stdin);// freopen("bubble6.out","w",stdout);int tt;qr(tt);while(tt--)solve();return 0;
}

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

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

相关文章

【C++二叉树】102.二叉树的层序遍历

107. 二叉树的层序遍历 II - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 层序遍历&#xff0c;但是要注意输出的结果是一个二维数组&#xff0c;不是一层一个值一个值的输出&#xff0c;而是要一层一层的输出。可以通过一个循环控制每一层的数据个数&#xff…

PyCharm 安装教程

传送门 PyCharm 是一款由 JetBrains 开发的强大的 Python 集成开发环境&#xff08;IDE&#xff09;。它支持多种功能&#xff0c;包括调试、代码补全、智能代码分析、版本控制集成等&#xff0c;特别适合开发 Python 项目。接下来&#xff0c;我们将详细介绍如何在不同操作系…

【C++高阶】解锁C++的深层魅力——探索特殊类的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C 类型转换 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C特殊类 &#x1f4d2;1. 不能被拷贝…

pyinstaller打包python程序

安装pyinstaller anaconda中直接pip install pyinstaller安装 程序打包 Anaconda Prompt进入python脚本所在目录直接用打包脚本 pyinstaller --onefile yourPyFile.py 打包后会在文件所在根目录生成两个文件夹build、dist dist中xx.exe文件就是打包好的程序

文字loading加载

效果 1. 导入库 import sys from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal from PyQt5.QtGui import QPainter, QFont, QColor, QBrush from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QProgressBar, QLabel 代码首先导入了P…

[创业之路-146] :如何理解:复杂的事情简单化,简单的事情标准化,标准的事情流程化,流程的事情数字化,数字化的事情自动化,自动化的事情智能化

目录 一、复杂的事情简单化 二、简单的事情标准化 1、标准化的定义与意义 2、简单事情标准化的实施步骤 3、标准化的案例分析 三、标准的事情流程化 1、流程化的定义与意义 2、标准事情流程化的实施步骤 3、流程化的案例分析 四、流程的事情数字化 1、定义与意义 2…

C++ | Leetcode C++题解之第409题最长回文串

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindrome(string s) {unordered_map<char, int> count;int ans 0;for (char c : s)count[c];for (auto p : count) {int v p.second;ans v / 2 * 2;if (v % 2 1 and ans % 2 0)ans;}retur…

【设计模式-外观】

这里写自定义目录标题 定义UML图角色作用代码使用场景 定义 为子系统中一组相关接口提供一致界面&#xff0c;定义一个高级接口&#xff0c;使得子系统更加容易使用。 UML图 角色作用 外观&#xff08;Facade&#xff09;角色&#xff1a;这是外观模式的核心&#xff0c;它知…

编程环境常用命令合集

cmd: python 进入python运行环境 exit()/quit()/ctrlZ 退出环境 rmdir /s venv 删除环境 pip命令&#xff1a; pip list 查看所有库 pip install <库> 安装库 -i <数据源>可指定安装数据源 pip install <库>x.x.x 安装指定版本的库 pip install --upgrade &…

LeetCode:2398. 预算内的最多机器人数目 双指针+单调队列,时间复杂度O(n)

2398. 预算内的最多机器人数目 today 2398. 预算内的最多机器人数目 题目描述 你有 n 个机器人&#xff0c;给你两个下标从0开始的整数数组 chargeTimes 和 runningCosts &#xff0c;两者长度都为 n 。第 i 个机器人充电时间为 chargeTimes[i] 单位时间&#xff0c;花费 ru…

macOS上谷歌浏览器的十大隐藏功能

谷歌浏览器&#xff08;Google Chrome&#xff09;在macOS上拥有一系列强大而隐蔽的特性&#xff0c;这些功能能显著提高您的浏览体验。从多设备同步到提升安全性和效率&#xff0c;这些被低估的功能等待着被发掘。我们将逐步探索这些功能&#xff0c;帮助您最大化利用谷歌浏览…

快速提升Python Pandas处理速度的秘诀

大家好&#xff0c;Python的Pandas库为数据处理和分析提供了丰富的功能&#xff0c;但当处理大规模数据时&#xff0c;性能问题往往成为瓶颈。本文将介绍一些在Pandas中进行性能优化的方法与技巧&#xff0c;帮助有效提升数据处理速度&#xff0c;优化代码运行效率。 1.数据类…

力扣题解815

大家好&#xff0c;欢迎来到无限大的频道。祝大家中秋节快乐​。 今日继续给大家带来力扣题解。 题目描述&#xff08;困难&#xff09;​&#xff1a; 公交路线 给你一个数组 routes &#xff0c;表示一系列公交线路&#xff0c;其中每个 routes[i] 表示一条公交线路&…

Python logging库(python日志库)Logger(记录器、收集器、采集器)、Handler(处理器)、Formatter(格式化器)、Log Level(日志级别)

文章目录 Python Logging库详解简介日志记录的基本概念1. Logger&#xff08;记录器&#xff09;&#xff1a;这是日志系统的入口点。每个记录器都有一个名称&#xff0c;并且记录器之间可以存在父子关系。2. Handler&#xff08;处理器&#xff09;&#xff1a;记录器将日志消…

网络安全-intigriti-0422-XSS-Challenge Write-up

目录 一、环境 二、解题 2.1看源码 一、环境 Intigriti April Challenge 二、解题 要求&#xff1a;弹出域名就算成功 2.1看源码 我们看到marge方法&#xff0c;肯定是原型链污染题目 接的是传参&#xff0c;我们可控的点在于qs.config和qs.settings&#xff0c;这两个可…

Java设计模式—面向对象设计原则(四) ----->接口隔离原则(ISP) (完整详解,附有代码+案例)

文章目录 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.4 接口隔离原则(ISP) 接口隔离原则&#xff1a;Interface Segregation Principle&#xff0c;简称ISP 3.4.1 概述 客户端测试类不应该被迫依赖于它不使用的方法&#xff1b;一个类对另一个类的依赖应该建立在最小的接…

Invoke-Maldaptive:一款针对LDAP SearchFilter的安全分析工具

关于Invoke-Maldaptive MaLDAPtive 是一款针对LDAP SearchFilter的安全分析工具&#xff0c;旨在用于对LDAP SearchFilter 执行安全解析、混淆、反混淆和安全检测。 其基础是 100% 定制的 C# LDAP 解析器&#xff0c;该解析器处理标记化和语法树解析以及众多自定义属性&#x…

Excel图片批量插入单元格排版处理插件【图片大师】

为了方便大家在图片的插入排版的重复工作中解放出来&#xff0c;最近发布了一款批量插入图片的插件&#xff0c;欢迎大家下载&#xff0c;免费试用。 这是图片的文件夹&#xff1a; 主要功能如下: 1&#xff0c;匹配单元格名称的多张图批量插入到一个单元格 该功能支持设置图…

机器学习的入门指南

机器学习的入门指南 机器学习&#xff08;Machine Learning, ML&#xff09;是人工智能&#xff08;AI&#xff09;领域中的一项核心技术&#xff0c;致力于通过数据和算法使计算机具备从经验中学习的能力。在当今的科技世界&#xff0c;机器学习被广泛应用于图像识别、语音识…

一个线性筛的多功能组合:筛法求质数+约数个数+约数和

F:\BC\2024\9>main1 活动代码页: 936 2 2X24 3 3X26 3X39 4X28 5 5X210 5X315 5X525 6X212 7 7X214 7X321 7X535 7X749 8X216 9X218 9X327 10X220 11 11X222 11X333 11X555 11X777 11X11121 12X224 13 13X226 13X339 13X565 13X791 13X11143 13X13169…