相交弦统计

Description

  • Kimi 最近得到了一个玩具,玩具由环和弦两个部分组成。环上有 2*N 个端
  • 点,而 N 条弦,每条连接其中的两个,既不重复也不遗漏。Kimi 对这些弦产生
  • 了浓厚的兴趣,他想数一数,一共有多少对弦是相交的呢?

    Input

  • 输入文件的第一行包含一个整数 N。
  • 接下来 N 行,每行包含两个整数 a、b(1≤a,b≤2*N),表示一条连接 a,b 的弦

    Output

  • 输出文件中近包含一个整数,表示相交弦的对

    Sample Input

    3 2
    5 2
    6 3

    Sample Output

    1

    题解

  • 两条弦相交只需要保证其中一条的一个点在另一条的两个端点之间
  • 然后树状数组or线段树维护一下前n个数有多少个左or右端点就好
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
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
#define lowbit(i) i&(-i)
using namespace std;
const int N=1e6;
ll tr[N<<1],n;
struct node{
int l,r;
}e[N];

int cmp(node x,node y){return x.l<y.l;}

void update(int x,int k){for(register int i=x;i<=n<<1;i+=lowbit(i))tr[i]+=k;}
ll ask(int x){ll ans=0; for(register int i=x;i;i-=lowbit(i))ans+=tr[i];return ans;}

int main(){
ios::sync_with_stdio(false);
while(cin>>n){
ll ans=0;
rep(i,1,n){
cin>>e[i].l>>e[i].r;
if(e[i].l>e[i].r)swap(e[i].l,e[i].r);
}
sort(e+1,e+n+1,cmp);
rep(i,1,n){
ans+=ask(e[i].r-1)-ask(e[i].l);
update(e[i].r,1);
}
cout<<ans<<endl;
}
}