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
Output
Input
Output
Input
Output
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;
}
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;
}
相关文章推荐
- codeforces contest 868 problem D(玄学)
- codeforces contest 785 b题
- codeforces contest 785 c题
- codeforces contest 868 problem C(补集 状压)
- codeforces contest 343 problem D(线段树+dfs序)
- Codeforces contest 311 problem E. Biologist(最大权闭合子图)
- codeforces com contest 855 problem D(数位DP)
- Codeforces Problem 709A Juicer(implementation)
- Codeforces Problem 711D Directed Roads(Tarjan判环)
- Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem(二分染色?/2-sat,好题)
- codeforce contest 103 problem D Time to Raid Cowavans(根号算法)
- Codeforces Round #320 (Div. 2) C - A Problem about Polyline
- Educational Codeforces Round 21 Problem E(Codeforces 808E) - 动态规划 - 贪心
- codeforces#253 D - Andrey and Problem里的数学知识
- Codeforces Round #253 (Div. 1) B. Andrey and Problem
- CODEFORCES problem 105A.Transmigration
- Codeforces Problem 332B - Maximum Absurdity
- Codeforces Round #400 (Div. 1 + Div. 2, combined)D - The Door Problem(2-sat)
- 2016-2017 CT S03E05: Codeforces Trainings Season 3 Episode 5 (2016 Stanford Local Programming Contest, Extended) I
- Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest(二月十日训练赛)