题目描述

给你一个长为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的更多相关文章

  1. [Ynoi2019模拟赛]Yuno loves sqrt technology II(二次离线莫队)

    二次离线莫队. 终于懂了 \(lxl\) 大爷发明的二次离线莫队,\(\%\%\%lxl\) 二次离线莫队,顾名思义就是将莫队离线两次.那怎么离线两次呢? 每当我们将 \([l,r]\) 移动右端点到 ...

  2. [Luogu5048] [Ynoi2019模拟赛]Yuno loves sqrt technology III[分块]

    题意 长为 \(n\) 的序列,询问区间众数,强制在线. \(n\leq 5\times 10^5\). 分析 考虑分块,暴力统计出整块到整块之间的众数次数. 然后答案还可能出现在两边的两个独立的块中 ...

  3. [luogu5048] [Ynoi2019模拟赛] Yuno loves sqrt technology III

    题目链接 洛谷. Solution 思路同[BZOJ2724] [Violet 6]蒲公英,只不过由于lxl过于毒瘤,我们有一些更巧妙的操作. 首先还是预处理\(f[l][r]\)表示\(l\sim ...

  4. [洛谷P5048][Ynoi2019模拟赛]Yuno loves sqrt technology III

    题目大意:有$n(n\leqslant5\times10^5)$个数,$m(m\leqslant5\times10^5)$个询问,每个询问问区间$[l,r]$中众数的出现次数 题解:分块,设块大小为$ ...

  5. 洛谷P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III(分块)

    传送门 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 用蒲公英那个分块的方法做结果两天没卡过去→_→ 首先我们分块,预处理块与块之间的答案,然后每次询问的时候拆成整块和两边剩下的元素 整块的答案很简 ...

  6. [Ynoi2019模拟赛]Yuno loves sqrt technology II

    题目大意: 给定一个长为\(n\)的序列,\(m\)次询问,每次查询一个区间的逆序对数. 32MB. 解题思路: 出题人题解 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 二次离线莫队. 对于每个区 ...

  7. 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 ...

  8. P5048 [[Ynoi2019模拟赛]Yuno loves sqrt technology III]

    为什么我感觉这题难度虚高啊-- 区间众数的出现次数- 计算器算一下 \(\sqrt 500000 = 708\) 然后我们发现这题的突破口? 考虑分块出来[L,R]块的众数出现个数 用 \(\text ...

  9. 洛谷 P5048 - [Ynoi2019 模拟赛] Yuno loves sqrt technology III(分块)

    题面传送门 qwq 感觉跟很多年前做过的一道题思路差不多罢,结果我竟然没想起那道题?!!所以说我 wtcl/wq 首先将 \(a_i\) 离散化. 如果允许离线那显然一遍莫队就能解决,复杂度 \(n\ ...

  10. 洛谷 P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I(分块+卡常)

    洛谷题面传送门 zszz,lxl 出的 DS 都是卡常题( 首先由于此题强制在线,因此考虑分块,我们那么待查询区间 \([l,r]\) 可以很自然地被分为三个部分: 左散块 中间的整块 右散块 那么这 ...

随机推荐

  1. asp.net Core HttpClient 出现Cannot access a disposed object. Object name: 'SocketsHttpHandler' 的问题。

    ASP.NET Core 部署在Centos 中 偶尔出现 One or more errors occurred. (Cannot access a disposed object.Object n ...

  2. 服务器四:多进程epoll

    #include <fcntl.h> #include <sys/socket.h> #include <netinet/in.h> #include <ar ...

  3. fullpage 全屏插件

     fullpage 全屏插件 全屏滚动效果,原生js也很好实现,主要是用 mousewheel 鼠标滚轮滚动事件, 来判断上滚动还是下滚动,之后设置每次滚动的高度为屏幕的高度即可.但是,虽然效果简单, ...

  4. 在 asp.net core 中使用类似 Application 的服务

    在 asp.net core 中使用类似 Application 的服务 Intro 在 asp.net 中,我们可以借助 Application 来保存一些服务器端全局变量,比如说服务器端同时在线的 ...

  5. 使用 phpstudy 搭建本地测试环境

    最近在为另一个部门配置一个多语言的网站,因为之前他们已经做过 英文和中文两种语言,这次帮他们添加其它几种语言,从GitLab 上拉下来的代码,是php环境做的,需要在本地跑起来,做完测试通过后再一次性 ...

  6. js实现自定义修改网页中表格信息

    项目中的打印页面,为提高用户体验,需要增自定修改表格内容的功能,以下是使用示意图(双击td标签部分的内容,可自定义修改): 以下是js插件源码,存为edit.js文件: var tbl, tbt; v ...

  7. UE4游戏开发基础命令

    在个人的Unrealengine账户中关联自己的GitHub账户成功之后,就可以访问UE4引擎的源码了. git clone -b release https://github.com/EpicGam ...

  8. 字符串转数字练习--String to Integer (atoi)

    Implement atoi which converts a string to an integer. The function first discards as many whitespace ...

  9. 【原】Java学习笔记033 - IO

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:继承关系中爷 ...

  10. iOS 多线程 NSOperation、NSOperationQueue

    1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...