E. Anton and Permutation
time limit per test

4 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

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.

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

【分析】题意很简单,就是动态的求区间逆序数。当时没做出来,赛后看了题解,学了发树状数组套主席树(内层主席树外层树状数组)学了一上午=_=借这个题好好说一下我对这个的理解吧,有啥不对的希望大佬能指出来OTZ.

主席树套树状数组就是梳妆数组的每一个节点都是一颗主席树,可以理解为线段树吧。主席树可以静态的求出排名,而动态的可以借助树状数组求,logn。而对于每一棵主席树,从i~n一棵一棵的建,可以这么理解,其实每一棵树都是一样的,包括所有的节点,只是有些节点隐藏起来了,只显现了一部分,显现了哪些部分呢?这就要考虑到树状数组了。树状数组的每一个节点,都与一个lowbit有关,刷过树状数组的应该知道,见下图

比如说对于4节点,(对于这个题目)初始就只显现了1~4区间的值。而对于6节点就之显现了5~6节点,注意,我这里说的是初始阶段。好嘞,现在来说修改。比如说我要把num[2]和num[6]换一下,那我们就把第二个节点的num[6]点亮(即显现),怎么点亮了?注意,我们一开始是按照从小到大的顺序存的,即每一刻主席树的叶子节点(包括未显现的)从左到右-->从小到大,那么就可以在lson,rson里找了,复杂度logn。找到之后就点亮,sz[]++.然后往上lowbit,将所有与之相关的节点的主席树相关位置都做同样的修改,复杂度logn。现在说查询,树状数组的查询会吧,就是lowbit求前缀和嘛,这个也一样,从上往下求lowbit前缀。对于每一刻主席树,先找到这个值,然后这个值(叶子节点)左边的叶子节点个数即是这棵书中比他小的,然后把所有相关的lowbit节点的线段树(不重合)的所有比他小的值得个数加起来,logn*logn。

嗯。。。这差不多就是我的理解了,要是有啥不对的,请大佬一定要指出来呀,嘻嘻。。。

听说还有一种叫 分块 的东西比这个简单,明天就学,学会了再写个做法,嘻嘻。。。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
using namespace std;
typedef long long ll;
const int N = 2e7+;
int sz[N],lson[N],rson[N],num[N],bit[N],n,total;
int addson() {return ++total;}
int lowbit(int x) {return x&(-x);}
void add(int &x,int l,int r,int y,int z){
if (!x)x=addson();
sz[x]+=z;
if (l==r) return;
int mid=(l+r)>>;
if (y<=mid) add(lson[x],l,mid,y,z);
else add(rson[x],mid+,r,y,z);
}
int ask(int x,int l,int r,int y){
if (!x) return ;
if (l==r) return sz[x];
int mid=(l+r)>>;
if (y<=mid) return ask(lson[x],l,mid,y);
else return sz[lson[x]]+ask(rson[x],mid+,r,y);
}
ll bigask(int x,int y){
ll now=;
while (x) {
now+=ask(bit[x],,n,y);
x-=lowbit(x);
}
return now;
}
void bigadd(int x,int y,int z){
while (x<=n) {
add(bit[x],,n,y,z);
x+=lowbit(x);
}
}
int main(){
int m;
scanf("%d%d",&n,&m);
ll sum=;
for(int i=;i<=n;i++)bigadd(i,num[i]=i,);
while (m--) {
int l,r;
scanf("%d %d",&l,&r);
if (l==r) {
printf("%lld\n",sum);
continue;
}
if (l>r)swap(l,r);
if (r-l>) {
sum-=*(bigask(r-,num[l])-bigask(l,num[l]));
sum+=*(bigask(r-,num[r])-bigask(l,num[r]));
}
if (num[l]<num[r]) ++sum;
else --sum;
printf("%lld\n",sum);
bigadd(l,num[l],-);
bigadd(l,num[r],);
bigadd(r,num[r],-);
bigadd(r,num[l],);
swap(num[l],num[r]);
}
return ;
}

Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)的更多相关文章

  1. Codeforces Round #404 (Div. 2) D. Anton and School - 2 数学

    D. Anton and School - 2 题目连接: http://codeforces.com/contest/785/problem/D Description As you probabl ...

  2. Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale 二分

    C. Anton and Fairy Tale 题目连接: http://codeforces.com/contest/785/problem/C Description Anton likes to ...

  3. Codeforces Round #404 (Div. 2) B. Anton and Classes 水题

    B. Anton and Classes 题目连接: http://codeforces.com/contest/785/problem/B Description Anton likes to pl ...

  4. Codeforces Round #404 (Div. 2) A - Anton and Polyhedrons 水题

    A - Anton and Polyhedrons 题目连接: http://codeforces.com/contest/785/problem/A Description Anton's favo ...

  5. 【组合数】【乘法逆元】 Codeforces Round #404 (Div. 2) D. Anton and School - 2

    http://codeforces.com/blog/entry/50996 官方题解讲得很明白,在这里我复述一下. 枚举每个左括号,考虑计算一定包含其的简单括号序列的个数,只考虑其及其左侧的左括号, ...

  6. Codeforces Round #404 (Div. 2) D. Anton and School - 2

    题目链接 转自 给你一个字符串问你能构造多少RSBS. #include<bits/stdc++.h> #define LL long long #define fi first #def ...

  7. 【二分】Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale

    当m>=n时,显然答案是n: 若m<n,在第m天之后,每天粮仓减少的量会形成等差数列,只需要二分到底在第几天,粮仓第一次下降到0即可. 若直接解不等式,可能会有误差,需要在答案旁边扫一下. ...

  8. Codeforces 605D - Board Game(树状数组套 set)

    Codeforces 题目传送门 & 洛谷题目传送门 事实上是一道非常容易的题 很容易想到如果 \(c_i\geq a_j\) 且 \(d_i\geq b_j\) 就连一条 \(i\to j\ ...

  9. 贪心 Codeforces Round #288 (Div. 2) B. Anton and currency you all know

    题目传送门 /* 题意:从前面找一个数字和末尾数字调换使得变成偶数且为最大 贪心:考虑两种情况:1. 有偶数且比末尾数字大(flag标记):2. 有偶数但都比末尾数字小(x位置标记) 仿照别人写的,再 ...

随机推荐

  1. [NOIP2017 TG D2T2]宝藏

    题目大意:给定一个有重边,边有权值的无向图.从某一个点出发,求到达所有的点需要的最少费用,并且限制两点之间只有一条路径.费用的计算公式为:所有边的费用之和.而边$x->y$的费用就为:$y$到初 ...

  2. 2014end

    人.事.物. 人一年了,从十六班到十六班,从j101到j101再到A207. 她:结婚,然后走了.就是这样,干脆得我都来不及留恋.是的,再也听不到她那很温柔语气,看不到她偶尔激动时就踮起脚尖.还记得晚 ...

  3. [Leetcode] Remove duplicates from sorted array 从已排序的数组中删除重复元素

    Given a sorted array, remove the duplicates in place such that each element appear only once and ret ...

  4. BZOJ5011 [JXOI2017]颜色 【线段树 + 主席树】

    题目链接 BZOJ5011 题解 一定只有我这种智障会用这么奇怪的方法做这道题.. 由题我们知道最后剩余的一定是一个区间,而且区间内的颜色不存在于区间外 所以我们的目的就是为了找到这样的区间的数量 区 ...

  5. 莫比乌斯反演题表II

    bzoj3994:[SDOI2015]约数个数和 **很好推+有个小结论bzoj3309:DZY Loves Math ***很好推+线筛某函数/卡常bzoj4816:[Sdoi2017]数字表格 * ...

  6. JavaScript渐变效果的实现

    鼠标移上去透明度渐渐增加,鼠标移出,透明度渐渐减小. 关键代码: view source   print? 1 var speed = 0; 2 if(target>obj.alpha){ 3 ...

  7. 编写clearedit的安卓控件

    1.写一个自定义的控件 public class ClearEditText extends AppCompatEditText implements View.OnFocusChangeListen ...

  8. oracle与mysql的group by语句

    之所以去纠那么细节的问题,是因为之前有过一个这样的场景: 有个同学,给了一条数据库的语句给我,问,为啥这样子的语句在oracle语句下执行不了. 1 select * from xx where xx ...

  9. tomcat 配置文件中设置JAVA_HOME

    Tomcat默认情况下会用系统的环境变量中找到JAVA_HOME和JRE_HOME.但是有的时候我们需要不同版本的JDK共存. 可以在${TOMCAT_HOME}/bin/setclasspath.b ...

  10. JavaBean定义、JSP中使用以及内省操作

        Apache commons 一系列的开源工具室非常值得学习的实现. 一 JavaBean定义     JavaBean是一种可重复使用.且跨平台的软件组件.JavaBean可分为两种:一种是 ...