codefroces 297E Mystic Carvings

时间:2022-09-15 21:13:02

problem:
一个圆上依次有1~2*n的数字。每个数字都有且只有另一个数字与他相连。选出三条线,使得每条线的两端之间隔的最少点(只包括被选择的6个点)的个数相等。
输入输出格式
输入格式:

The first line contains integer n(3<=n<=10^5) — the number of lines.

Each of the following n n n lines contains two integers ai​,bi​ (1<=ai,bi<=2n), which means that there is a line carved on the ice connecting the ai –th and bi​ –th endpoint.

It's guaranteed that each endpoints touches exactly one line.

输出格式:

Print the number of ways to build the caves.

Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

输入输出样例
输入样例#1:

4
5 4
1 2
6 7
8 3

输出样例#1:

2

输入样例#2:

8
1 7
2 4
3 9
5 11
6 8
10 16
13 15
14 12

输出样例#2:

6

说明

The second sample corresponds to the figure in the problem statement.

六个点三条边有以下五种可能:

codefroces 297E Mystic Carvings

明显只有第1个和第4个可以。但是这2个情况不好求

可以求出总方案再减去不合法方案

此题有两种写fa♂:

第一种是树状数组

假设当前直线i a->b(a<b)

在直线左边的直线数为x,右边的直线数为y,与i相♂蕉的直线数为z

显然有x+y+z+1=n

第3种情况就是x*y

第2,5种是(x+y)*z

但是因为每个点都有边连出,且圆上无

所以z=b-a-1-2*x

第二种是主席树,了解一下

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
lol c[],n,m;
int a[],b[],p[];
lol ans1,ans2,ans;
void add(int x,int d)
{
while (x<=m)
{
c[x]+=d;
x+=(x&(-x));
}
}
int query(int x)
{
int s=;
while (x)
{
s+=c[x];
x-=(x&(-x));
}
return s;
}
int main()
{int i;
cin>>n;
m=*n;
for (i=;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
p[a[i]]=b[i];
p[b[i]]=a[i];
}
for (i=;i<=m;i++)
{
if (i<p[i]) continue;
int x=query(i)-query(p[i]-);
int z=i-p[i]--x*;
add(p[i],);
int y=n--x-z;
ans1+=x*y;
ans2+=(x+y)*z;
}
ans=n*(n-)*(n-)/;
cout<<ans-ans1-ans2/;
}