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. Buck电路匹配和二极管仿真模式

    Buck带同步整流,关闭二极管仿真模式会使空载损耗大 利用二极管仿真模式提高降压转换器轻负载效率 Buck电路工作原理以及三种工作模式分析   一.Buck电路原理图 Buck电路,又称降压电路,其基 ...

  2. mybatis的两种分页方式:RowBounds和PageHelper

    原理:拦截器. 使用方法: RowBounds:在mapper.java中的方法中传入RowBounds对象. RowBounds rowBounds = new RowBounds(offset, ...

  3. IPv4(三)地址掩码

    回顾网络类型确定 回顾一下之前学过的如果确定IP地址网络号,这里先不考虑子网. 首先通过首个八位组字节规则很容易确定IP地址属于那个网络: 如果第1位是0,则是A类地址: 如果前两位是10,则是B类地 ...

  4. bugzilla 系列1安装

    安装好mysql yum install gcc perl* mod_perl-devel -y wget https://ftp.mozilla.org/pub/mozilla.org/webtoo ...

  5. JAVA学习第五十二课 — IO流(六)File对象

    File类 用来给文件或者目录封装成对象 方便对文件与目录的属性信息进行操作 File对象能够作为參数传递给流的构造函数 一.构造函数和分隔符 public static void FileDemo( ...

  6. python MySQLdb Windows下安装教程及问题解决方法(python2.7)

    使用python访问mysql,需要一系列安装 linux下MySQLdb安装见  Python MySQLdb在Linux下的快速安装http://www.jb51.net/article/6574 ...

  7. RedHat7 防火墙设置以及端口设置

    1.查看防火墙状态,root用户登录,执行命令systemctl status firewalld 2.开启防火墙:systemctl start firewalld 3.关闭防火墙:systemct ...

  8. 安装anaconda及pytorch

    安装anaconda,下载64位版本安装https://www.anaconda.com/download/    官网比较慢,可到清华开源镜像站上下载 环境变量: D:\Anaconda3;D:\A ...

  9. split_brain

    脑裂 系统中两个或多个部分开始独立工作

  10. Oracle数据库之SQL基础和分支循环

    一.SQL基础语言 DECLARE --声明 a ); --变量或对象 BEGIN a:='小明';-- := 表示给一个变量赋值 dbms_output.put_line(a); --输出用 dbm ...