Portal

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的更多相关文章

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

  2. Anton and Permutation

    Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input standa ...

  3. Codeforces 785 E. Anton and Permutation(分块,树状数组)

    Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求 ...

  4. Codeforces 785E. Anton and Permutation

    题目链接:http://codeforces.com/problemset/problem/785/E 其实可以CDQ分治... 我们只要用一个数据结构支持单点修改,区间查询比一个数大(小)的数字有多 ...

  5. [CF785E]Anton and Permutation

    题目大意:有一串数为$1\sim n(n\leqslant2\times10^5)$,$m(m\leqslant5\times10^4)$次询问,每次问交换位置为$l,r$的两个数后数列中逆序对的个数 ...

  6. Codeforces 785E Anton and Permutation(分块)

    [题目链接] http://codeforces.com/contest/785/problem/E [题目大意] 一个1到n顺序排列的数列,每次选择两个位置的数进行交换,求交换后的数列的逆序对数 [ ...

  7. CodeForces 785E Anton and Permutation 分块

    题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...

  8. 【codeforces 785E】Anton and Permutation

    [题目链接]:http://codeforces.com/problemset/problem/785/E [题意] 给你一个初始序列1..n顺序 然后每次让你交换任意两个位置上面的数字; 让你实时输 ...

  9. 题解 CF785E 【Anton and Permutation】

    考虑用分块解决这个题,一次交换对当前逆序对个数的影响是,加上两倍的在区间\([l+1,r-1]\)中比\(a_r\)小的元素个数,减去两倍的在区间\([l+1,r-1]\)中比\(a_l\)小的元素个 ...

随机推荐

  1. junit3对比junit4

    本文内容摘自junit实战,感谢作者的无私奉献. 个人觉得每个开源包的版本对比意义不大,闲来无事,这里就来整理一下好了.本文名为junit3对比junit4,但是我通过这篇博客主要也是想统一的来整理下 ...

  2. LINUX读写文件区别

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  3. ios 判断屏幕显示是@2x还是@3x来调用字体大小

    传统font大小适配可能会根据屏幕宽度与iphone5或iphone6宽度的一个比例来适配.但如果有这样一个需求,在显示@2x图片的手机上显示一种字体,在显示@3x图片的手机上显示另一个固定大小的字体 ...

  4. java IO(六):额外功能处理流

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  5. 04_Javascript初步第三天

    事件 内联模型.脚本模型,DOM2级模型 <!--内联模型--> <input type="button" value="bt1" oncli ...

  6. HTML5 拖放(Drag 和 Drop)详解与实例

    简介 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 先点击一个小例子:在用户开始拖动 <p> 元素时执行 JavaSc ...

  7. js控制滚动条滑动

    window.scrollTo(0,document.body.scrollHeight);或者通过设置Location的hash属性参见:http://www.cnblogs.com/oospace ...

  8. curl访问nagios中Host Status Details For All Host Groups页面的方法

    由于进入nagios要输入用户名与密码才能进入,故用curl模拟输入用户名与密码取得当前所有主机的报警信息: # curl -u nagiosadmin:password http://192.168 ...

  9. nagios 数据更新不及时的问题

    配置nagios的时候发现一个问题,就是改变了某个主机或者服务的描述之后,在主页信息总是更新很慢,而且告警信息还是老的信息,重启多次 nagios甚至重启主机都没有解决,其实这些都是由于nagios每 ...

  10. 隐藏C语言黑窗口

    隐藏C语言程序运行的黑窗口,加入预编译命令: (预编译,Linker链接,windows模式,黑窗口是dos模式) #pragma comment(linker,"/subsystem:\& ...