AtCoder problem 017

C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;



class BIT {

public:

	int size_ = 1;

	vector<long long> bit;



	void init(int sz) {

		size_ = sz + 2;

		bit.resize(size_ + 2, 0);

	}

	void add(int pos, long long x) {

		pos++;

		while (pos <= size_) {

			bit[pos] += x;

			pos += (pos & -pos);

		}

	}

	long long sum(int pos) {

		long long s = 0; pos++;

		while (pos >= 1) {

			s += bit[pos];

			pos -= (pos & -pos);

		}

		return s;

	}

};



// Input

long long N, M;

long long L[1 << 18], R[1 << 18];



// Kazoeage

long long V1[1 << 18], V2[1 << 18], V3[1 << 18];



int main() {

	// Step #1. Input

	cin >> N >> M;

	for (int i = 1; i <= M; i++) cin >> L[i] >> R[i];



	// Step #2. Get Answer1

	long long Answer1 = 0;

	for (int i = 1; i <= M; i++) V3[L[i]] += 1;

	for (int i = 1; i <= M; i++) V3[R[i]] += 1;

	for (int i = 1; i <= N; i++) Answer1 += V3[i] * (V3[i] - 1LL) / 2LL;



	// Step #3. Get Answer2

	long long Answer2 = 0;

	for (int i = 1; i <= M; i++) V1[R[i]] += 1;

	for (int i = 1; i <= M; i++) V2[L[i] - 1] += 1;

	for (int i = 1; i <= N; i++) V1[i] += V1[i - 1];

	for (int i = 1; i <= N; i++) Answer2 += V1[i] * V2[i];



	// Step #4. Sorting

	vector<pair<long long, long long>> vec;

	for (int i = 1; i <= M; i++) vec.push_back(make_pair(R[i], L[i]));

	sort(vec.begin(), vec.end());



	// Step #5. Get Answer3

	long long Answer3 = 0;

	BIT Z; Z.init(N + 2);

	for (int i = 0; i < vec.size(); i++) {

		long long cl = vec[i].second, cr = vec[i].first;

		long long ret = Z.sum(cr) - Z.sum(cl);

		Answer3 += ret;

		Z.add(cl, 1);

	}



	// Step #6. Output The Answer!

	long long Total = M * (M - 1) / 2LL;

	long long SumAns = Answer1 + Answer2 + Answer3;

	cout << Total - SumAns << endl;

	return 0;

}


Python solution: # でつoO(YOU PLAY WITH THE CARDS YOU'RE DEALT..)
import sys
def main():
    input = sys.stdin.readline
    N, M = map(int, input().split())
    S = [[] for _ in range(N)]
    T = [[] for _ in range(N)]
    E = []
    for i in range(M):
        s, t = map(lambda x: int(x) - 1, input().split())
        S[s].append(i)
        T[t].append(i)
        E.append((s, t))
    st = SegmentTree(N, f=lambda a, b: a + b)
    ans = 0
    for n in range(N):
        for i in T[n]:
            s, t = E[i]
            st.modify_at(s, -1)
        for i in T[n]:
            s, t = E[i]
            ans += st.query(s + 1, t)
        st.modify_at(n, len(S[n]))
    print(ans)

class SegmentTree:
    __slots__ = ('__n', '__d', '__f', '__e')

    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i << 1], d[i << 1 | 1])

    def __repr__(self) -> str:
        n = self.__n
        return str([self.get_at(i) for i in range(n)])

    def get_at(self, index):
        return self.__d[index + self.__n]

    def set_at(self, index, new_value):
        i, d, f = index + self.__n, self.__d, self.__f
        if d[i] == new_value: return
        d[i], i = new_value, i >> 1
        while i: d[i], i = f(d[i << 1], d[i << 1 | 1]), i >> 1

    def modify_at(self, index, value):
        self.set_at(index, self.__f(self.__d[index + self.__n], value))

    def query(self, from_inclusive, to_exclusive):
        ans = self.__e()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__d, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l + 1
            if r & 1: ans, r = f(d[r - 1], ans), r - 1
            l, r = l >> 1, r >> 1
        return ans

    def query_all(self):
        return self.__d[1]

    def bisect_left(self, func, from_inclusive=None, to_exclusive=None):
        '''func()がTrueになるもっとも左のindexを探す
        '''
        n, f, d, v = self.__n, self.__f, self.__d, self.__e()
        l = (from_inclusive if from_inclusive else 0) + n
        r = (to_exclusive if to_exclusive else n) + n
        h = 0
        while l < r:
            if l & 1:
                nv = f(v, d[l])
                if func(nv): return self.__single_bisect_left(func, l, v)
                v, l = nv, l + 1
            l, r, h = l >> 1, r >> 1, h + 1
        if r == 0: return n
        for i in range(h, 0, -1):
            if ((r + 1) << i <= n + n):
                nv = f(v, d[r])
                if func(nv): return self.__single_bisect_left(func, r, v)
                v, r = nv, r + 1
            r <<= 1
        return n

    def __single_bisect_left(self, func, root, left_val):
        n, f, d = self.__n, self.__f, self.__d
        i, v = root, left_val
        while i < n:
            i <<= 1
            nv = f(v, d[i])
            if not func(nv): i, v = i + 1, nv
        return i - n

if __name__ == '__main__':
    main()