题解 CF785E Anton and Permutation
Posted lhm-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 CF785E Anton and Permutation相关的知识,希望对你有一定的参考价值。
考虑用分块解决这个题,一次交换对当前逆序对个数的影响是,加上两倍的在区间([l+1,r-1])中比(a_r)小的元素个数,减去两倍的在区间([l+1,r-1])中比(a_l)小的元素个数,再根据(a_l)和(a_r)的大小关系决定这两个位置对答案的影响。
可以用(vector)来维护每个块内元素有序,然后就可以支持询问了。
(code:)
#include<bits/stdc++.h>
#define maxn 200010
#define lower(a,x) lower_bound(ve[a].begin(),ve[a].end(),x)
#define upper(a,x) upper_bound(ve[a].begin(),ve[a].end(),x)
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c==‘-‘)flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,k,S;
int bel[maxn],a[maxn];
ll ans;
vector<int> ve[maxn];
void change(int l,int r)
{
if(bel[l]!=bel[r])
{
ve[bel[l]].erase(lower(bel[l],a[l])),ve[bel[l]].insert(upper(bel[l],a[r]),a[r]);
ve[bel[r]].erase(lower(bel[r],a[r])),ve[bel[r]].insert(upper(bel[r],a[l]),a[l]);
}
swap(a[l],a[r]);
}
int query(int l,int r,int v)
{
if(l>r) return 0;
int cnt=0;
for(int i=l;i<=min(S*bel[l],r);++i) cnt+=(a[i]<v);
if(bel[l]==bel[r]) return cnt;
for(int i=S*(bel[r]-1)+1;i<=r;++i) cnt+=(a[i]<v);
for(int i=bel[l]+1;i<=bel[r]-1;++i) cnt+=lower(i,v)-ve[i].begin();
return cnt;
}
int main()
{
read(n),read(k),S=sqrt(n);
for(int i=1;i<=n;++i) a[i]=i,bel[i]=(i-1)/S+1,ve[bel[i]].push_back(a[i]);
while(k--)
{
int l,r;
read(l),read(r);
if(l>r) swap(l,r);
if(l==r)
{
printf("%lld
",ans);
continue;
}
ans+=2*(query(l+1,r-1,a[r])-query(l+1,r-1,a[l]));
if(a[l]<a[r]) ans++;
else ans--;
change(l,r),printf("%lld
",ans);
}
return 0;
}
以上是关于题解 CF785E Anton and Permutation的主要内容,如果未能解决你的问题,请参考以下文章
codeforces785E Anton and Permutation
CodeForces 785E Anton and Permutation