circle （容斥原理+数据结构）

${C}_{n}^{3}-\sum _{x}f\left[x\right]\left(n-1-f\left[x\right]-g\left[x\right]\right)-\frac{\sum _{x}g\left[x\right]\left(n-1-g\left[x\right]\right)}{2}$

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=200100;
typedef long long LL;

int f[maxn];
int g[maxn];

int bit[maxn];
int a[maxn];

int n;

int Sum(int x)
{
int sum=0;
while (x)
{
sum+=bit[x];
x-=(x&(-x));
}
return sum;
}

int Query(int L,int R)
{
return Sum(R)-Sum(L-1);
}

{
while (x<=2*n)
{
bit[x]++;
x+=(x&(-x));
}
}

int main()
{
freopen("circle.in","r",stdin);
freopen("circle.out","w",stdout);

scanf("%d",&n);
for (int i=1; i<=n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x]=y;
a[y]=x;
}

for (int i=2*n; i>=1; i--)
if (i<a[i])
{
f[i]=Query(i,a[i]);
}

for (int i=1; i<=2*n; i++) bit[i]=0;
for (int i=1; i<=2*n; i++)
if (i<a[i])
{
g[i]=Query(i,a[i]);
}

for (int i=1; i<=2*n; i++) bit[i]=0;
for (int i=2*n; i>=1; i--)
if (a[i]<i)
{
g[ a[i] ]+=Query(a[i],i);
}

LL ans=n*(n-1LL)*(n-2LL)/6LL;
LL temp=0;
for (int i=1; i<=2*n; i++)
if (i<a[i])
{
ans-=( (long long)f[i]*(long long)(n-1LL-f[i]-g[i]) );
temp+=( (long long)g[i]*(long long)(n-1LL-g[i]) );
}
temp>>=1;
ans-=temp;
printf("%I64d\n",ans);

return 0;
}

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客