Buggy python submission (verdict: Runtime Error):
from enum import IntEnum

class Action(IntEnum):
  ADD = 1
  SEARCH = 2
  REMOVE = 3

class Color(IntEnum):
  BLACK=0
  RED=1

  @staticmethod
  def flip(c):
    return [Color.RED,Color.BLACK][c.value]

class Node:
  __slots__ = ('value','left','right','color','valid')

  def __init__(self,value):
    self.value=value
    self.left=Leaf
    self.right=Leaf
    self.color=Color.RED
    self.valid=True

  def flip_color(self):
    self.color==Color.RED

  def is_red(self):
    return self.color == Color.RED

  def __str__(self):
    return ('('+str(self.left)+','+str(self.value)+','+str(self.right)+')')

class LeafNode(Node):
  def __init__(self):
    self.value=None
    self.left=None
    self.right=None
    self.color=None
    self.valid=False

  def flip_color(self):
    pass

  def is_red(self):
    return False

  def __str__(self):
    return 'Leaf'

Leaf=LeafNode()

class RedBlackBST:
  def __init__(self):
    self.root=Leaf

  def add(self,value):
    def _add(node):
      if node is Leaf:
        node=Node(value)
      if node.value>value:
        node.left=_add(node.right)
      elif node.value<value:
        node.right=_add(node.right)
      else:
        if not node.valid:
          node.valid=True
      node=self._balance(node)
      return node
    self.root=_add(self.root)
    self.root.color=Color.BLACK

  def _balance(self,node):
    if node.right.is_red() and not node.left.is_red():
      node=self._rotate_left(node)
    if node.left.is_red() and node.left.left.is_red():
      node=self._rotate_right(node)
    if node.left.is_red() and node.right.is_red():
      node = self._flip_colors(node)
    return node

  def _rotate_left(self,node):
    x=node.right
    node.right=x.left
    x.left=node
    x.color=node.color
    node.color=Color.RED
    return x

  def _rotate_right(self,node):
    x=node.left
    node.left=x.right
    x.right=node
    x.color=node.color
    node.color=Color.RED
    return x

  def _flip_colors(self,node):
    node.flip_color()
    node.left.flip_color()
    node.right.flip_color()
    return node

  def remove(self,value):
    def _remove(node):
      if node is Leaf:
        return
      if node.value>value:
        _remove(node.left)
      elif node.value<value:
        _remove(node.right)
      else:
        node.valid=False
    _remove(self.root)

  def count(self,min_,max_):
    def _range(node):
      if node is Leaf:
        return 0
      if node.value>max_:
        return _range(node.left)
      elif node.value<min_:
        return _range(node.right)
      else:
        count= _range(node.left)+_range(node.right)
        if node.valid:
          count+=1
        return count
    return _range(self.root)

  def __str__(self):
    return str(self.root)

def count_intersections(segments):
  segments.sort()
  tree=RedBlackBST()
  count=0
  for seg in segments:
    x,action,y=seg
    if action==Action.SEARCH:
      count+=tree.count(*y)
    elif action==Action.ADD:
      tree.add(y)
    elif action == Action.REMOVE:
      tree.remove(y)
  return count


n=int(input())
segs=[]

for i in range(n):
  x1,y1,x2,y2=map(int,input().split())
  if x1>x2 or y1>y2:
    x1,x2=x2,x1
    y1,y2=y2,y1
  if x1==x2:
    segs.append((x1,Action.SEARCH,(y1,y2)))
  else:
    segs.append((x1,Action.ADD,y1))
    segs.append((x2,Action.REMOVE,y2))
print(count_intersections(segs))







Fixed submission:
import sys
file_input = sys.stdin
n = file_input.readline()

EP = []
l = -1000000001
u = 1000000001
vs_x = set()
h_num = 0

for line in file_input:
  x1, y1, x2, y2 = map(int, line.split())
  if x1 == x2:
    if y1 < y2:
      EP.append((y1, l, x1))
      EP.append((y2, u, x1))
    else:
      EP.append((y1, u, x1))
      EP.append((y2, l, x1))
    vs_x.add(x1)
  else:
    if x1 < x2:
      EP.append((y1, x1, x2))
    else:
      EP.append((y1, x2, x1))
    h_num += 1

class BinaryIndexedTree:
  def __init__(self, n):
    self.data = [0] *(n+1)
    self.num = n

  def switch(self, i, d):
    while  i <= self.num:
      self.data[i] += d
      i += i & -i

  def sum(self, i):
    s = 0
    while  i:
      s += self.data[i]
      i -= i & -i
    return s

  def seg_sum(self, a, b):
    return self.sum(b) - self.sum(a- 1)

import bisect

EP.sort()
BIT = BinaryIndexedTree(len(vs_x))
vs_x = [l] + sorted(vs_x)
d_vs_x = {e:i for i, e in enumerate(vs_x)}

cnt = 0

for p in EP:
  e = p[1]
  if e== l:
    BIT.switch(d_vs_x[p[2]], 1)
  elif e==u:
    BIT.switch(d_vs_x[p[2]], -1)
  else:
    l_x = bisect.bisect_left(vs_x, e)
    r_x = bisect.bisect(vs_x, p[2]) -1
    cnt += BIT.seg_sum(l_x,r_x)
    h_num -= 1
  if h_num ==0:
    break
print(cnt)


#一言：平面操作でユーグリッド空間上の線分交点を求める
#処理の流れ：入力された線分端点をyを基準に昇順にリストに入れる。→順番に取り出す。→下恥ならBSTに挿入。・上端ならBSTから削除。入れたものがx軸と交差したらそこで探索を開始する。
#計算量：O(nlogn+k)（二分木探索の計算量nlogn+交点k）