[Ynoi2019模拟赛]Yuno loves sqrt technology I
题目描述
给你一个长为n的排列,m次询问,每次查询一个区间的逆序对数,强制在线。
题解
MD不卡了。。TMD一点都卡不动。
强制在线的话也没啥好一点的方法,只能分块预处理了。
对于每个块,我们设lef[i]表示i到这个i这个元素所在块的块头的区间逆序对,rig[i]表示到块尾的逆序对。
在设一个cnt[i][j]表示从第i个块到第j个块的逆序对。
然后考虑如何处理询问。
整块之间的可以直接O(1)取答案,对于散块,我们需要求出散块内部的答案,散块对整块的答案,散块对散块的答案。
对于散块内的,因为散块在当前块中一定是它的前缀或后缀,所以我们直接O(1)取答案。
对于散块对整块的,我们可以在维护一个tag[i][j]表示前i个块,大于/小于j的元素有多少个,然后询问就扫描散块,前缀和统计即可。
对于散块对散块的,可以在每个块内维护元素的相对大小,然后对于两个不相交的区间,可以用桶排+扫描求出逆序对。
但还有一个特殊情况,就是lr在同一个块里,前面的方法不是很实用。
我们设当前块头尾h,那么答案可以表示为ans(h-r)-ans(h-l)-ans(h~l,l~r),前两个部分已经求过了,后面的用桶排+扫描即可。
不过常数略大,开2s应该能过。
代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("Ofast","inline","unroll-loops")
#pragma GCC optimize ("no-stack-protector")
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cassert>
#include <cmath>
#define N 100002
#define M 340
using namespace std;
typedef long long ll;
int n,m,tr[N],mis[M],rnk[N],n1,ji[M],be[N],a[N],b[M],lef[N],tag1[M][N],tag2[M][N],rig[N],tong[N];
int q[N],pos[N];
ll ans,cnt[M][M];
inline void add(int x,int y){while(x<=n)tr[x]+=y,x+=x&-x;}
inline int query(int x){int ans=;while(x)ans+=tr[x],x-=x&-x;return ans;}
inline int merge(int l2,int r2,int l1,int r1){
int ans=;
for(int i=l1;i<=r1;++i)ji[rnk[i]]=a[i];
q[]=;
for(int i=;i<=n1;++i)if(ji[i]){
q[++q[]]=ji[i];ji[i]=;
}
int p=;
for(int i=l2;i<=r2;++i)ji[rnk[i]]=a[i];
for(int i=;i<=n1;++i)if(ji[i]){
while(p<=q[]&&(!p||q[p]<=ji[i]))p++;p--;
ans+=p;ji[i]=;
}
return ans;
}
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
int main(){
n=rd();m=rd();
n1=;
for(int i=;i<=n;++i)a[i]=rd(),be[i]=(i-)/n1+,pos[a[i]]=i;
for(int i=;i<=be[n];++i){
int l=(i-)*n1+,r=min(n,i*n1);int top=;
for(int j=l;j<=r;++j)b[++top]=a[j];
sort(b+,b+top+);
for(int j=;j<=top;++j)rnk[pos[b[j]]]=j;
for(int j=l;j<=r;++j){
lef[j]=query(n-a[j]+);
if(j!=l)lef[j]+=lef[j-];
add(n-a[j]+,);tong[n-a[j]+]=;
}
int moss=;
for(int j=n;j>=;--j){
moss+=tong[n-j+];
tag2[i][j]=tag2[i-][j]+moss;
}
for(int j=l;j<=r;++j)add(n-a[j]+,-),tong[n-a[j]+]=;
for(int j=r;j>=l;--j){
rig[j]=query(a[j]);
if(j!=r)rig[j]+=rig[j+];
add(a[j],);tong[a[j]]=;
}
moss=;
for(int j=;j<=n;++j){
moss+=tong[j];
tag1[i][j]=tag1[i-][j]+moss;
}
for(int j=l;j<=r;++j)add(a[j],-),tong[a[j]]=;
}
for(int i=;i<=be[n];++i){
cnt[i][i]=lef[min(n,i*n1)];
for(int j=i+;j<=be[n];++j){
cnt[i][j]=cnt[i][j-];int x=min(n,n1*j);
for(int k=(j-)*n1+;k<=x;++k){
cnt[i][j]+=tag2[j-][a[k]]-tag2[i-][a[k]];
}
cnt[i][j]+=lef[x];
}
}
int l,r;
while(m--){
l=rd();r=rd();l^=ans;r^=ans;
if(l>r)l^=r^=l^=r;ans=;
// if(r>n||l<1){ans=0;puts("0");continue;}
if(be[l]==be[r]){
ans=lef[r];if(l!=(be[l]-)*n1+)ans-=lef[l-],ans-=merge((be[l]-)*n1+,l-,l,r);
}
else{
int st=be[l]+,en=be[r]-;
for(int i=l;i<=be[l]*n1;++i)ans=ans+tag1[en][a[i]]-tag1[st-][a[i]];
for(int i=en*n1+;i<=r;++i)ans=ans+tag2[en][a[i]]-tag2[st-][a[i]];
ans+=cnt[st][en]+rig[l]+lef[r];
ans+=merge(l,(st-)*n1,en*n1+,r);
}
printf("%lld\n",ans);
}
return ;
}
[Ynoi2019模拟赛]Yuno loves sqrt technology I的更多相关文章
- [Ynoi2019模拟赛]Yuno loves sqrt technology II(二次离线莫队)
二次离线莫队. 终于懂了 \(lxl\) 大爷发明的二次离线莫队,\(\%\%\%lxl\) 二次离线莫队,顾名思义就是将莫队离线两次.那怎么离线两次呢? 每当我们将 \([l,r]\) 移动右端点到 ...
- [Luogu5048] [Ynoi2019模拟赛]Yuno loves sqrt technology III[分块]
题意 长为 \(n\) 的序列,询问区间众数,强制在线. \(n\leq 5\times 10^5\). 分析 考虑分块,暴力统计出整块到整块之间的众数次数. 然后答案还可能出现在两边的两个独立的块中 ...
- [luogu5048] [Ynoi2019模拟赛] Yuno loves sqrt technology III
题目链接 洛谷. Solution 思路同[BZOJ2724] [Violet 6]蒲公英,只不过由于lxl过于毒瘤,我们有一些更巧妙的操作. 首先还是预处理\(f[l][r]\)表示\(l\sim ...
- [洛谷P5048][Ynoi2019模拟赛]Yuno loves sqrt technology III
题目大意:有$n(n\leqslant5\times10^5)$个数,$m(m\leqslant5\times10^5)$个询问,每个询问问区间$[l,r]$中众数的出现次数 题解:分块,设块大小为$ ...
- 洛谷P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III(分块)
传送门 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 用蒲公英那个分块的方法做结果两天没卡过去→_→ 首先我们分块,预处理块与块之间的答案,然后每次询问的时候拆成整块和两边剩下的元素 整块的答案很简 ...
- [Ynoi2019模拟赛]Yuno loves sqrt technology II
题目大意: 给定一个长为\(n\)的序列,\(m\)次询问,每次查询一个区间的逆序对数. 32MB. 解题思路: 出题人题解 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 二次离线莫队. 对于每个区 ...
- Luogu P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III 分块
这才是真正的$N\sqrt{N}$吧$qwq$ 记录每个数$vl$出现的位置$s[vl]$,和每个数$a[i]=vl$是第几个$vl$,记为$P[i]$,然后预处理出块$[i,j]$区间的答案$f[i ...
- P5048 [[Ynoi2019模拟赛]Yuno loves sqrt technology III]
为什么我感觉这题难度虚高啊-- 区间众数的出现次数- 计算器算一下 \(\sqrt 500000 = 708\) 然后我们发现这题的突破口? 考虑分块出来[L,R]块的众数出现个数 用 \(\text ...
- 洛谷 P5048 - [Ynoi2019 模拟赛] Yuno loves sqrt technology III(分块)
题面传送门 qwq 感觉跟很多年前做过的一道题思路差不多罢,结果我竟然没想起那道题?!!所以说我 wtcl/wq 首先将 \(a_i\) 离散化. 如果允许离线那显然一遍莫队就能解决,复杂度 \(n\ ...
- 洛谷 P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I(分块+卡常)
洛谷题面传送门 zszz,lxl 出的 DS 都是卡常题( 首先由于此题强制在线,因此考虑分块,我们那么待查询区间 \([l,r]\) 可以很自然地被分为三个部分: 左散块 中间的整块 右散块 那么这 ...
随机推荐
- Eclipse目录实解
从左1图中可以看到,其中的src/main/java存放java文件,src/main/resources存放项目用到的资源(js,css,图片,文件等).下面的两个文件夹是用来存放测试文件和资源的( ...
- weUI之分页查询实现
本文旨在介绍移动端h5分页查询实现 1.前端html 前端基于weui 样式库实现 参考http://jqweui.com/ <div class="weui-search-bar ...
- Yii2设计模式——注册树模式
应用举例 在Yii.php中: <?php class ServiceLocator extends Component { //保存实例化的对象,每个对象都是单例,且有唯一string类型的I ...
- MySQL分组查询与连接查询
一,分组查询 使用ORDER BY子句将表中的数据分成若干组(还是按行显示) 语法: SELECT 字段名[,聚集函数] FROM 表名 [WHERE子句] GROUP BY 要分组的字段名 [ORD ...
- animate-queue和step-animate
Step-animate: 分为3部分:{配置},{step:function(){...},duration:1000} <div id="warpper" style=& ...
- MyDAL - 引用类型对象 .DeepClone() 深度克隆[深度复制] 工具 使用
索引: 目录索引 一.API 列表 .DeepClone() 用于 Model / Entity / ... ... 等引用类型对象的深度克隆 特性说明 1.不需要对对象做任何特殊处理,直接 .Dee ...
- c#面试题汇总(1)
c#面试题汇总 From: https://www.cnblogs.com/suzhiyong1988/p/5069385.html 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化 ...
- Win7环境 搭建IIS环境。发布asp.net MVC项目到IIS(第二期)
在IIS环境中给发布项目修改域名,192.168.1.1:8081 ---->> www.preject.com 一.在网站主页中,1找到绑定网站.2编辑. 二.修改网站配置参数. 三. ...
- js 倒计时跳转
用js实现简单的倒计时结束页面跳转效果,主要用到setInterval()和clearInterval()方法,页面跳转使用window.location.href = " ".倒 ...
- 【原】使用IDEA创建Maven工程时提示"...xxx/pom.xml already exists in VFS"的解决
问题:使用IDEA创建Maven工程时提示"...xxx/pom.xml already exists in VFS",怎么办? 解决:如果只是删除工程,还会有这样的提示.说到底, ...