Codeforces785E - Anton and Permutation
Description
对一个长度为\(n(n\leq2\times10^5)\)的数列\(a\)进行\(m(m\leq5\times10^4)\)次操作,数列初始时为\(\{1,2,...,n\}\)。每次操作交换数列中的两个数\(a_L\)和\(a_R\),并询问此时数列\(a\)中的逆序对数。
Solution
交换\(a_L\)和\(a_R\)时,会影响逆序对数的只有下标在\((L,R)\)之间,数值在\(a_L\)和\(a_R\)之间的数(钦定\(L<R\))。设这样的数有\(k\)个,那么若\(a_L<a_R\),逆序对数会增加\(2k+1\);若\(a_L>a_R\),逆序对数会减少\(2k+1\)。
所以只要使用一种数据结构,支持单点修改和查询区间内数值在某个范围内的数的个数。分块即可解决这个问题。维护每个块内的数有序,那么就可以通过二分查找以\(O(log\sqrt n)\)求出块内满足条件的数的个数。对于修改,修改之后将所在块再次排序即可。
时间复杂度\(O(m\sqrt nlog\sqrt n)。\)
Code
//Anton and Permutation
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long lint;
inline char gc()
{
static char now[1<<16],*S,*T;
if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
return *S++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
int const N=2e5+1e3;
int n,m,n0,a[N];
int blk[N],fr[N],to[N],b[N];
int query(int t,int x,int y)
{
int L=upper_bound(b+fr[t],b+to[t]+1,x)-b;
int R=lower_bound(b+fr[t],b+to[t]+1,y)-b-1;
return R-L+1;
}
void update(int t)
{
for(int i=fr[t];i<=to[t];i++) b[i]=a[i];
sort(b+fr[t],b+to[t]+1);
}
int main()
{
n=read(),m=read(); n0=sqrt(n);
for(int i=1;i<=n;i++) a[i]=b[i]=i;
for(int i=1;i<=n;i++) blk[i]=(i-1)/n0+1;
for(int i=1;i<=blk[n];i++) fr[i]=(i-1)*n0+1,to[i]=i*n0;
to[blk[n]]=n;
lint ans=0;
for(int i=1;i<=m;i++)
{
int L=read(),R=read(); if(L>R) swap(L,R);
if(L==R) {printf("%lld\n",ans); continue;}
int x=a[L],y=a[R]; lint res=0,f=1;
if(x>y) swap(x,y),f=-1;
if(blk[L]==blk[R]) for(int i=L;i<=R;i++) res+=(x<a[i]&&a[i]<y);
else
{
for(int i=L;i<=to[blk[L]];i++) res+=(x<a[i]&&a[i]<y);
for(int t=blk[L]+1;t<=blk[R]-1;t++) res+=query(t,x,y);
for(int i=fr[blk[R]];i<=R;i++) res+=(x<a[i]&&a[i]<y);
}
ans+=2*res*f; if(a[L]<a[R]) ans++; else ans--;
swap(a[L],a[R]); update(blk[L]),update(blk[R]);
printf("%lld\n",ans);
}
return 0;
}
P.S.
要用long long来保存逆序对数。
存在\(L=R\)的情况,可以特判一下。
Codeforces785E - Anton and Permutation的更多相关文章
- Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)
E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...
- Anton and Permutation
Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input standa ...
- Codeforces 785 E. Anton and Permutation(分块,树状数组)
Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求 ...
- Codeforces 785E. Anton and Permutation
题目链接:http://codeforces.com/problemset/problem/785/E 其实可以CDQ分治... 我们只要用一个数据结构支持单点修改,区间查询比一个数大(小)的数字有多 ...
- [CF785E]Anton and Permutation
题目大意:有一串数为$1\sim n(n\leqslant2\times10^5)$,$m(m\leqslant5\times10^4)$次询问,每次问交换位置为$l,r$的两个数后数列中逆序对的个数 ...
- Codeforces 785E Anton and Permutation(分块)
[题目链接] http://codeforces.com/contest/785/problem/E [题目大意] 一个1到n顺序排列的数列,每次选择两个位置的数进行交换,求交换后的数列的逆序对数 [ ...
- CodeForces 785E Anton and Permutation 分块
题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...
- 【codeforces 785E】Anton and Permutation
[题目链接]:http://codeforces.com/problemset/problem/785/E [题意] 给你一个初始序列1..n顺序 然后每次让你交换任意两个位置上面的数字; 让你实时输 ...
- 题解 CF785E 【Anton and Permutation】
考虑用分块解决这个题,一次交换对当前逆序对个数的影响是,加上两倍的在区间\([l+1,r-1]\)中比\(a_r\)小的元素个数,减去两倍的在区间\([l+1,r-1]\)中比\(a_l\)小的元素个 ...
随机推荐
- web、pc、wap、app的区别
通常情况下web=pc,wap=app,前者指电脑用的程序,后者指手机用的程序. 更深层的区别是,pc电脑上软件,web电脑上的网页,wap手机上的网页,app手机用软件
- 第一个简单的maven项目
学习一个新的东西,最快的方式就是实践.所以我们也不用多说什么了,直接拿一个项目来练手.下面的整理取自maven权威指南,在一堆maven资料中,我觉得这本书写的最好. 简介 我们介绍一个用Maven ...
- Linux exec与文件描述符
看到好几篇文章讲述exec都是一知半解,所以我尽量说的清楚明白一些.本文首先讲述Linux文件描述符,然后是exec,最后举例说明exec I/O重定向及其用法. 概念:exec命令用于调用并执行指令 ...
- PHP中文网上的分页代码
page.php <html> <head> <meta http-equiv="CONTENT-TYPE" content="text/h ...
- Struts2是什么?
Struts2是什么: Struts2是整合了struts1和webwork的技术优点的使用广泛的MVC框架: Struts2的特点: 1.基于MVC框架,结构清晰,便于开发人员掌控开发流程: 2.使 ...
- 自动化安装DHCP配置脚本
DHCP配置脚本: #!/bin/sh NET=192.168.6.0 MASK=255.255.255.0 RANGE="192.168.6.50 192.168.6.100" ...
- Cypher查询语言--Neo4j 综合(四)
目录 返回节点 返回关系 返回属性 带特殊字符的标识符 列的别名 可选属性 特别的结果 查询中的返回部分,返回途中定义的感兴趣的部分.可以为节点.关系或其上的属性. 图 返回节点 返回一个节点,在 ...
- ABP 多租户 对应多数据库 租户启动报错
什么是多租户? “软件多租户是指一个软件体系结构,其中一个软件实例在一个服务器上运行,并为多个租户提供服务*租户是一组共享具有软件实例特定权限的公共访问权限的用户. 架构中,软件应用程序旨在为每个租户 ...
- Linux history命令
history命令主要用于显示历史命令, 重新执行历史命令. Linux系统当你在shell(控制台)中输入并执行命令时,shell会自动把你的命令记录到历史列表中,一般保存在用户目录下的.bash_ ...
- JMS基础篇(二)
简介 异构集成是消息发挥作用的一个领域,大型公司内部可能会遇到很多的平台,Java,.net或者公司自己的平台等. 传送消息还应该支持异步机制,以提高系统整体的性能.异步传输一条消息意味着,发送者不必 ...