Anton likes permutations, especially he likes to permute their elements. Note that a permutation of n elements is a sequence of numbers {a1, a2, ..., an}, in which every number from 1 to n appears exactly once.

One day Anton got a new permutation and started to play with it. He does the following operation q times: he takes two elements of the permutation and swaps these elements. After each operation he asks his friend Vanya, how many inversions there are in the new permutation. The number of inversions in a permutation is the number of distinct pairs (i, j) such that 1 ≤ i < j ≤ n and ai > aj.

Vanya is tired of answering Anton's silly questions. So he asked you to write a program that would answer these questions instead of him.

Initially Anton's permutation was {1, 2, ..., n}, that is ai = i for all i such that 1 ≤ i ≤ n.

Input

The first line of the input contains two integers n and q (1 ≤ n ≤ 200 000, 1 ≤ q ≤ 50 000) — the length of the permutation and the number of operations that Anton does.

Each of the following q lines of the input contains two integers li and ri (1 ≤ li, ri ≤ n) — the indices of elements that Anton swaps during the i-th operation. Note that indices of elements that Anton swaps during the i-th operation can coincide. Elements in the permutation are numbered starting with one.

Output

Output q lines. The i-th line of the output is the number of inversions in the Anton's permutation after the i-th operation.

Example

Input
5 4
4 5
2 4
2 5
2 2
Output
1
4
3
3
Input
2 1
2 1
Output
1
Input
6 7
1 4
3 5
2 3
3 3
3 6
2 1
5 1
Output
5
6
7
7
10
11
8

Note

Consider the first sample.

After the first Anton's operation the permutation will be {1, 2, 3, 5, 4}. There is only one inversion in it: (4, 5).

After the second Anton's operation the permutation will be {1, 5, 3, 2, 4}. There are four inversions: (2, 3), (2, 4), (2, 5) and (3, 4).

After the third Anton's operation the permutation will be {1, 4, 3, 2, 5}. There are three inversions: (2, 3), (2, 4) and (3, 4).

After the fourth Anton's operation the permutation doesn't change, so there are still three inversions.

题意:

初始数列,a[]为顺序排列。问每次交换u,v两个位置的数字后,逆序对数量。

由于数状数组解决逆序对是离线操作,不支持交换操作(就我所知是如此)。反正不好快速查询u,v位置的数和之间的数大小关系。

所以用分块乱搞,如果u,v距离不远,暴力即可,如果太远,可以用分块好的有序数组快速得到排名关系。每一次操作O(lg+sqrt)。

感觉不难实现,而且马上打CF了,所以难得写一遍了。

不过有序vector的删除和加入以前倒是没有实现过,get。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#define ps push_back
#define Siz(x) (int)x.size()
using namespace std;
typedef long long LL;
LL ans = 0LL;
const int maxn = + ;
int n,q; //n个数,m个操作
int num; //num个块
int block; // 块的长度
int L[maxn], R[maxn]; //每个块的左右边界
int a[maxn]; //n个数,用与单个比较
int belong[maxn]; //位置属于哪一块
vector<int> bit[maxn]; //每个块,用于lower_bound快速找个数。
void init(){
block=sqrt(n);
num=(n-)/block+;
for (int i=;i<=num;i++){
L[i]=(i-)*block+;
R[i]=i*block;
} R[num]=n; //修改细节
for(int i=;i<=n;i++)
belong[i]=(i-)/block + ;
for(int i=;i<=num;i++)
for (int j=L[i];j<=R[i];j++)
bit[i].ps(j); //每一块的有序序列
}
int query(int l,int r,int v){
if (l>r) return ;
int ans=;
if(belong[l]==belong[r]){
for(int i=l;i<=r;++i)
if(a[i]<v) ++ans;
return ans;
}
int id=belong[l];
for(int i=l;i<=R[id];++i){
if(a[i]<v) ans++;
}
for(int i=belong[l]+;i<=belong[r]-;i++){
int p2=lower_bound(bit[i].begin(),bit[i].end(),v)-bit[i].begin();
ans+=p2;
}
id=belong[r];
for(int i=L[id];i<=r;i++){
if(a[i]<v) ans++;
}
return ans;
}
void update(int l,int r){
int uu=a[l];
int vv=a[r];
int id=belong[l];
bit[id].erase(lower_bound(bit[id].begin(),bit[id].end(),uu));//删去。
bit[id].insert(upper_bound(bit[id].begin(),bit[id].end(),vv),vv);//加入
id = belong[r];
bit[id].erase(lower_bound(bit[id].begin(),bit[id].end(),vv));
bit[id].insert(upper_bound(bit[id].begin(),bit[id].end(),uu),uu);
swap(a[l],a[r]);
}
int main(){
scanf("%d %d",&n, &q);
for (int i=;i<=n;i++) a[i] = i;
init();
while(q--){
int u,v;
scanf("%d%d",&u,&v);
if(u==v){
printf("%lld\n",ans);
continue;
}
if(u>v) swap(u,v);
int t1=query(u+,v-,a[u]);//期间比左边小的
int t2=v--u-+-t1;//期间比左边大的
ans-=t1; ans+=t2;
t1=query(u+,v-,a[v]);
t2=v--u-+-t1;
ans+=t1; ans-=t2;
if(a[u]<a[v])++ans;
else ans--;
printf("%lld\n",ans);
update(u,v);
}
return ;
}

CF785CAnton and Permutation(分块 动态逆序对)的更多相关文章

  1. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  2. BZOJ 3295: [Cqoi2011]动态逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3865  Solved: 1298[Submit][Sta ...

  3. 【Luogu1393】动态逆序对(CDQ分治)

    [Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...

  4. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

  5. bzoj3295[Cqoi2011]动态逆序对 树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5987  Solved: 2080[Submit][Sta ...

  6. cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )

    hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...

  7. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  8. P3157 [CQOI2011]动态逆序对

    P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...

  9. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

    3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...

随机推荐

  1. Struts2学习九----------处理结果类型(input)

    © 版权声明:本文为博主原创文章,转载请注明出处 Struts2处理结果类型 - SUCCESS:Action正确的执行完成,返回相应的视图,success是name属性的默认值 - ERROR:表示 ...

  2. Oracle SQL性能优化 - 根据大表关联更新小表

    需求: 小表数据量20w条左右,大表数据量在4kw条左右,需要根据大表筛选出150w条左右的数据并关联更新小表中5k左右的数据. 性能问题: 对筛选条件中涉及的字段加index后,如下常规的updat ...

  3. 【Java】 Spring依赖注入小试牛刀:编写第一个Spring ApplicationContext Demo

    0  Spring的依赖注入大致是这样工作的: 将对象如何构造(ID是什么?是什么类型?给属性设置什么值?给构造函数传入什么值?)写入外部XML文件里.在调用者需要调用某个类时,不自行构造该类的对象, ...

  4. 重新编译Nginx指导手册【修复静态编译Openssl的Nginx漏洞 】(转)

    1. 概述    当前爆出了Openssl漏洞,会泄露隐私信息,涉及的机器较多,环境迥异,导致修复方案都有所不同.不少服务器使用的Nginx,是静态编译opensssl,直接将openssl编译到ng ...

  5. XMPP资源绑定(Resource Binding)

    一个XMPP的账号由三部分组成: 用户名(user/node),域名(domain)和资源(resource) .例如 alice@xmpp.irusher.com/mobile ,user部分(或n ...

  6. eclipse maven 刷新报错

    问题描述: An internal error occurred during: "Loading descriptor for cmbc_wms.".java.lang.Null ...

  7. GC入门指南(二)------GC工作原理

    本系列博客旨在帮助大家理解java垃圾收集器及其工作原理,这是系列的第二篇. java垃圾回收事实上是由一个能够进行自己主动内存管理的进程完毕的,这使得程序猿在写代码的时候不必过多考虑内存释放与回收的 ...

  8. EasyPlayer windows RTSP播放器OCX插件使用说明

    鉴于大家对于EasyPlayer插件的使用还不太熟悉,特此写一篇插件的使用文档,供大家参考:EasyPlayer插件有两种,一种是基于IE的ActiveX控件,一种是基于FireFox(也支持多浏览器 ...

  9. MongoDB的对象的创建

    package com.voice.db; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.Mon ...

  10. Notepad++ QuickText 插件的 HTML 配置: \Notepad++\plugins\Config\QuickText.ini

    # 缩写的注解 abbr=<abbr title=''>$</abbr> # 覆盖默认的文本方向 bdo=<bdo dir='rtl'>$</bdo> ...