正题
题目链接:https://www.luogu.com.cn/problem/CF297E
题目大意
2∗n2*n2∗n个点的圆,nnn条圆上不交的弦,选择三条使得每条弦对应的弧上的点数量相等。
解题思路
就这5种情况,其中满足条件的是222和555,我们用容斥去掉1,3,41,3,41,3,4即可。
对于每条弦,我们用树状数组维护出在它左边和右边且不与他相交的弦的数量x,yx,yx,y,然后与它相交的数量就是z=n−1−x−yz=n-1-x-yz=n−1−x−y。
第一种情况的个数就是x∗yx*yx∗y,第3,43,43,4种的和就是z∗(x+y)z*(x+y)z∗(x+y)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define lowbit(x) (x&-x)
using namespace std;
const int N=2e5+10;
ll n,ans;
struct node{ll l,r;
}p[N];
struct Tree_Array{ll t[N];void Change(ll x,ll val){while(x<=2*n){t[x]+=val;x+=lowbit(x);}return;}ll Ask(ll x){ll ans=0;while(x){ans+=t[x];x-=lowbit(x);}return ans;}
}Ta,Tp;
bool cmp(node x,node y)
{return x.r<y.r;}
int main()
{scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld%lld",&p[i].l,&p[i].r);if(p[i].r<p[i].l) swap(p[i].l,p[i].r);}sort(p+1,p+1+n,cmp);for(ll i=1;i<=n;i++)Ta.Change(p[i].l,1);ans=n*(n-1)*(n-2)/6ll;for(ll i=1;i<=n;i++){Ta.Change(p[i].l,-1);ll z=Tp.Ask(p[i].l)+Ta.Ask(p[i].r)-Ta.Ask(p[i].l);ll x=(p[i].r-1-p[i].l-z)/2,y=n-1-z-x;ans-=x*y+z*(x+y)/2;Tp.Change(p[i].l,1);Tp.Change(p[i].r,-1);}printf("%lld",ans);
}