CF540E Infinite Inversions 题解
在无限长的数轴上,每次交换两个数,求最后逆序对数量。
观察到最终有很多 \([l,r]\) 的连续段,且段的数量是 \(\Theta(n)\) 的,考虑计算贡献。
先建立类似珂朵莉树的结构,将原数轴划分为许多段。
然后从左到右扫描每一个段,考虑逆序对的贡献。
如果当前的段是一个单点,此前的单点贡献当且仅当 \(a_j>a_i\),一个区间贡献当且仅当 \([l,r]\) 满足 \(l>a_i\)。因为 \(r>a_i\) 必然没有贡献,而 \(l \le a_i \le r\) 说明这个区间被分割开了,矛盾!
如果当前段是一个区间,此前的区间一定不会有贡献,那么单点有贡献当且仅当 \(a_i >l\),因为 \(a_i>r\) 一定没贡献,\(l\le a_i \le r\) 说明区间被分割,矛盾!
于是一个区间的段可以看成 \(r-l+1\) 个 值为 \(l\) 的点。
用树状数组求逆序对即可。
#include <bits/stdc++.h>
#define int long long
#define umap unordered_map
#define vint vector<int>
#define ll long long
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define ull unsigned long long
#define uint unsigned int
#define rg register
#define il inline
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define sqr(x) ((x)*(x))
using namespace std;
const int INF=0x3f3f3f3f;
inline int read()
{
int w=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
w=(w<<1)+(w<<3)+(ch^48);
ch=getchar();
}
return w*f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1e6+10;
struct odt
{
struct node
{
int l,r;
mutable int v;
node(int l=0,int r=0,int v=0):l(l),r(r),v(v){}
bool operator <(const node &b)const
{
return l<b.l;
}
};
set<node> S;
auto split(int pos)
{
auto it=S.lower_bound(pos);
if(it!=S.end()&&it->l==pos) return it;
--it;
int l=it->l,r=it->r;
S.erase(it);
S.insert(node(l,pos-1,l));
return S.insert(node(pos,r,pos)).first;
}
auto get(int x)
{
auto it=split(x);
int l=it->l,r=it->r;
if(l==r) return it;
S.erase(it);
S.insert(node(x+1,r,x+1));
return S.insert(node(x,x,x)).first;
}
}t;
int xi[N<<2],cntx;int n;
struct bit
{
int tr[N<<4];
int lowbit(int x)
{
return x&-x;
}
void add(int x,int k)
{
for(;x<=cntx;x+=lowbit(x)) tr[x]+=k;
}
int query(int x)
{
int res=0;
for(;x>0;x-=lowbit(x)) res+=tr[x];
return res;
}
int query(int l,int r)
{
return query(r)-query(l-1);
}
}tr;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
cin>>n;
t.S.insert(odt::node(1,1e9+1,1));
for(int i=1,a,b;i<=n;++i)
{
a=read(),b=read();
auto it1=t.get(a),it2=t.get(b);
swap(it1->v,it2->v);
}
// cerr<<1<<endl;
// cout<<t.S.size()<<endl;
for(auto i:t.S)
{
// cout<<i.l<<" "<<i.r<<" "<<i.v<<endl;
xi[++cntx]=i.v,xi[++cntx]=i.l,xi[++cntx]=i.r;
}
sort(xi+1,xi+cntx+1);
cntx=unique(xi+1,xi+cntx+1)-xi-1;
int ans=0;
for(auto i:t.S)
{
int val=lower_bound(xi+1,xi+cntx+1,i.v)-xi;
// cerr<<val<<endl;
tr.add(val,i.r-i.l+1);
ans+=tr.query(val+1,cntx)*(i.r-i.l+1);
}
cout<<ans<<endl;
#ifndef ONLINE_JUDGE
fprintf(stderr,"%f\n",1.0*clock()/CLOCKS_PER_SEC);
#endif
return 0;
}

浙公网安备 33010602011771号