Codeforces 297E - Mystic Carvings

Gavin

好题。

因为只需要三条线段,直接分讨一下情况,实际上只有五种(CF 题解图片炸了,补一张自己画的)。

考虑所有限制,只有第二种和第五种是合法的,但是这两者都需要定一求二计算,很难算啊。

考虑正难则反,用总方案数 (n3)\binom{n}{3} 减去第一、三、四种分别的方案数。

第一种很好算,断环为链以后就是二维数点,至于第三、四种分开算仍然难处理,需要合在一起算。

做完了。

在具体实现中,因为一根线把圆分成了左右两部分,我们只需要分别处理两边与其不相交的线段个数就可以了。

然后就是三、四两种情况会算重,取一半就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/******************************
- @GavinCQTD
- "E. Mystic Carvings"
- # https://codeforces.com/problemset/problem/297/E
- 3000 ms
******************************/

#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstring>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;

class Fenwick{
private:
int tree[200005],n;

int lowbit(int x){
return x&(-x);
}

public:
int query(int x){
int ans=0;
while(x!=0){
ans += tree[x];
x -= lowbit(x);
}
return ans;
}

void update(int x,int k){
while(x<=n){
tree[x] += k;
x += lowbit(x);
}
}

void reset(){
memset(tree,0,sizeof(tree));
}

Fenwick(){}
Fenwick(int n):n(n){}
};

struct Element{
int a,b,l,r;
};

int n;
ull ans=0;
Element el[100005];
Fenwick fen;

int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);

cin >> n;
for(int i=1;i<=n;i++){
cin >> el[i].a >> el[i].b;
if(el[i].a>el[i].b){
swap(el[i].a,el[i].b);
}
}

fen = Fenwick(2*n);

stable_sort(el+1,el+n+1,[](Element x,Element y){
return x.a<y.a;
});

for(int i=n;i>=1;i--){
el[i].l = fen.query(el[i].b);
fen.update(el[i].b,1);
}

for(int i=1;i<=n;i++){
el[i].r += fen.query(el[i].a);
}

fen.reset();

for(int i=1;i<=n;i++){
el[i].r += fen.query(2*n)-fen.query(el[i].b);
fen.update(el[i].b,1);
}

fen.reset();

for(int i=1;i<=n;i++){
fen.update(el[i].a,1);
}
for(int i=1;i<=n;i++){
el[i].r += fen.query(2*n)-fen.query(el[i].b);
}

// #1 (|||)
ull ans1=0;
for(int i=1;i<=n;i++){
ans1 += (ull)el[i].l*(ull)el[i].r;
}

// #3 / #4 (XI / H)
ull ans2=0;
for(int i=1;i<=n;i++){
ans2 += (ull)(el[i].l+el[i].r)*(ull)(n-el[i].l-el[i].r-1);
}

cout << (ull)n*(ull)(n-1)*(ull)(n-2)/6-ans1-ans2/2 << "\n";

return 0;
}
  • 标题: Codeforces 297E - Mystic Carvings
  • 作者: Gavin
  • 创建于 : 2026-01-30 00:32:00
  • 更新于 : 2026-01-30 00:32:00
  • 链接: https://gavin-blog.pages.dev/2026/codeforces-297e-mystic-carvings/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
目录
Codeforces 297E - Mystic Carvings