您的位置:首页 > 其它

codeforces contest 785 problem E(分块)

2017-10-07 18:19 489 查看
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 15 1


Output
5
6
7
7
10
118


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.

题意:一个1-n的数组,q次询问,每次交换两个数的位置 问每次操作后的逆序数对

解:关键思想就是每次交换这两个数后 对序列的影响 在区间范围之外的不产生影响,区间范围之内的统计比a[l] 和 a[r]小的个数就能算出答案

如果是整块直接二分查找,不是整块暴力枚举

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int N = 300000+10;
typedef long long LL;
int lx
, rx
, a
, id
;
vector<int>p
;
void init(int n)
{
for(int i=1; i<=n; i++) a[i]=i;
int k=(int)sqrt(1.0*n),i;
for(i=1; i*k<n; i++)
{
lx[i]=(i-1)*k+1,rx[i]=i*k,p[i].clear();
for(int j=lx[i]; j<=rx[i]; j++) p[i].push_back(a[j]),id[j]=i;
}
lx[i]=(i-1)*k+1,rx[i]=n,p[i].clear();
for(int j=lx[i]; j<=rx[i]; j++) p[i].push_back(a[j]),id[j]=i;
return ;
}
LL ans;
int query(int l,int r,int v)
{
if(l>r) return 0;
int l1=id[l],r1=id[r],sum=0;
if(l1==r1)
{
for(int i=l;i<=r;i++) if(a[i]<v) sum++;
return sum;
}
else
{
for(int i=l;i<=rx[l1];i++) if(a[i]<v) sum++;
for(int i=lx[r1];i<=r;i++) if(a[i]<v) sum++;
for(int i=l1+1;i<r1;i++) sum+=(lower_bound(p[i].begin(),p[i].end(),v)-p[i].begin());
return sum;
}
}
void update(int l,int r)
{
int x=a[l],y=a[r];
int l1=id[l], r1=id[r];
p[l1].erase(lower_bound(p[l1].begin(),p[l1].end(),x));
p[r1].erase(lower_bound(p[r1].begin(),p[r1].end(),y));
p[l1].insert(upper_bound(p[l1].begin(),p[l1].end(),a[r]),a[r]);
p[r1].insert(upper_bound(p[r1].begin(),p[r1].end(),a[l]),a[l]);
swap(a[l],a[r]);
return ;
}

int main()
{
int n, q;
scanf("%d %d", &n, &q);
init(n);
ans=0;
for(int i=0; i<q; i++)
{
int l, r;
scanf("%d %d", &l, &r);
if(l==r)
{
printf("%I64d\n",ans);
continue;
}
if(l>r) swap(l,r);
ans+=(r-l-1-2*query(l+1,r-1,a[l]));
ans-=(r-l-1-2*query(l+1,r-1,a[r]));
if(a[l]<a[r]) ans++;
else ans--;
update(l,r);
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: