Problem:
Librarian's Work
Japanese Animal Girl Library (JAG Library) is famous for a long bookshelf. It contains $N$ books numbered from $1$ to $N$ from left to right. The weight of the $i$-th book is $w_i$.
One day, naughty Fox Jiro shuffled the order of the books on the shelf! The order has become a permutation $b_1, ..., b_N$ from left to right. Fox Hanako, a librarian of JAG Library, must restore the original order. She can rearrange a permutation of books $p_1, ..., p_N$ by performing either operation A or operation B described below, with
arbitrary two integers $l$ and $r$ such that $1 \leq l < r \leq N$ holds.
Operation A:
A-1. Remove $p_l$ from the shelf.
A-2. Shift books between $p_{l+1}$ and $p_r$ to $left$.
A-3. Insert $p_l$ into the $right$ of $p_r$.
Operation B:
B-1. Remove $p_r$ from the shelf.
B-2. Shift books between $p_l$ and $p_{r-1}$ to $right$.
B-3. Insert $p_r$ into the $left$ of $p_l$.
This picture illustrates the orders of the books before and after applying operation A and B for $p = (3,1,4,5,2,6), l = 2, r = 5$.
Since the books are heavy, operation A needs $\sum_{i=l+1}^r w_{p_i} + C \times (r-l) \times w_{p_l}$ units of labor and operation B needs $\sum_{i=l}^{r-1} w_{p_i} + C \times (r-l) \times w_{p_r}$ units of labor, where $C$ is a given constant positive integer.
Hanako must restore the initial order from $b_i, ..., b_N$ by performing these operations repeatedly. Find the minimum sum of labor to achieve it.
Input
The input consists of a single test case formatted as follows.
$N$ $C$
$b_1$ $w_{b_1}$
:
$b_N$ $w_{b_N}$
The first line conists of two integers $N$ and $C$ ($1 \leq N \leq 10^5, 1 \leq C \leq 100$). The ($i+1$)-th line consists of two integers $b_i$ and $w_{b_i}$ ($1 \leq b_i \leq N, 1 \leq w_{b_i} \leq 10^5$). The sequence ($b_1, ..., b_N$) is a permutation of ($1, ..., N$).
Output
Print the minimum sum of labor in one line.
Sample Input 1
3 2
2 3
3 4
1 2
Output for Sample Input 1
15
Performing operation B with $l = 1, r = 3$, i.e. removing book 1 then inserting it into the left of book 2 is an optimal solution. It costs $(3+4)+2\times2\times2=15$ units of labor.
Sample Input 2
3 2
1 2
2 3
3 3
Output for Sample Input 2
0
Sample Input 3
10 5
8 3
10 6
5 8
2 7
7 6
1 9
9 3
6 2
4 5
3 5
Output for Sample Input 3
824

Submitted solutions:

code_snippet: // AOJ #2853 Librarian's Work
// 2025.3.28

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int MAXN = 100005;

vector<ll> tree(MAXN);
vector<int> tot(MAXN);

int lowbit(int x) { return x & -x; }
void update_tree(int x, ll y) { while (x < MAXN) tree[x] += y, x += lowbit(x); }
void update_tot(int x, int y) { while (x < MAXN) tot[x] += y, x += lowbit(x);  }

ll query_tree(int x) {
    ll s = 0;
    while (x > 0) {
        s += tree[x];
        x -= lowbit(x);
    }
    return s;
}

int query_tot(int x) {
    int s = 0;
    while (x > 0) {
        s += tot[x];
        x -= lowbit(x);
    }
    return s;
}

// 1-indexedで扱う
vector<pair<int, ll>> arr, tmp;

ll solve(int l, int r, ll C) {
    if (l == r) return 0;
    int mid = (l + r) / 2;
    ll ans = solve(l, mid, C) + solve(mid + 1, r, C);
    int p = l, q = mid + 1;
    ll sumSec = 0, cnt = 0;
    for (int i = l; i <= r; i++) {
        if (q > r || (p <= mid && arr[p] < arr[q])) {
            ans += sumSec + cnt * arr[p].second;
            ans += (C - 1) * query_tree(arr[p].second);
            ans += (C - 1) * (query_tot(MAXN - 1) - query_tot(arr[p].second)) * arr[p].second;
            tmp[i] = arr[p++];
        } else {
            sumSec += arr[q].second;
            cnt++;
            update_tree(arr[q].second, arr[q].second);
            update_tot(arr[q].second, 1);
            tmp[i] = arr[q++];
        }
    }
    for (int i = mid + 1; i <= r; i++) {
        update_tree(arr[i].second, -arr[i].second);
        update_tot(arr[i].second, -1);
    }
    for (int i = l; i <= r; i++) arr[i] = tmp[i];
    return ans;
}

int main() {
    int N = Cin(), C = Cin();

    arr.resize(N + 1);
    tmp.resize(N + 1);
    for (int i = 1; i <= N; i++) {
        int u = Cin(), v = Cin();
        arr[i] = make_pair(u, v);
    }
    Cout(solve(1, N, C));
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 7272
final_rank: 1

code_snippet: // AOJ #2853 Librarian's Work
// 2025.3.28

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int MAXN = 100005;

vector<ll> tree(MAXN);
vector<int> tot(MAXN);

int lowbit(int x) { return x & -x; }
void update_tree(int x, ll y) { while (x < MAXN) tree[x] += y, x += lowbit(x); }
void update_tot(int x, int y) { while (x < MAXN) tot[x] += y, x += lowbit(x);  }

ll query_tree(int x) {
    ll s = 0;
    while (x > 0) {
        s += tree[x];
        x -= lowbit(x);
    }
    return s;
}

int query_tot(int x) {
    int s = 0;
    while (x > 0) {
        s += tot[x];
        x -= lowbit(x);
    }
    return s;
}

// 1-indexedで扱う
vector<pair<int, ll>> arr, tmp;

ll solve(int l, int r, ll C) {
    if (l == r) return 0;
    int mid = (l + r) / 2;
    ll ans = solve(l, mid, C) + solve(mid + 1, r, C);
    int p = l, q = mid + 1;
    ll sumSec = 0, cnt = 0;
    for (int i = l; i <= r; i++) {
        if (q > r || (p <= mid && arr[p] < arr[q])) {
            ans += sumSec + cnt * arr[p].second;
            ans += (C - 1) * query_tree(arr[p].second);
            ans += (C - 1) * (query_tot(MAXN - 1) - query_tot(arr[p].second)) * arr[p].second;
            tmp[i] = arr[p++];
        } else {
            sumSec += arr[q].second;
            cnt++;
            update_tree(arr[q].second, arr[q].second);
            update_tot(arr[q].second, 1);
            tmp[i] = arr[q++];
        }
    }
    for (int i = mid + 1; i <= r; i++) {
        update_tree(arr[i].second, -arr[i].second);
        update_tot(arr[i].second, -1);
    }
    for (int i = l; i <= r; i++) arr[i] = tmp[i];
    return ans;
}

int main() {
    int N = Cin(), C = Cin();

    arr.resize(N + 1);
    tmp.resize(N + 1);
    for (int i = 1; i <= N; i++) {
        int u = Cin(), v = Cin();
        arr[i] = make_pair(u, v);
    }
    Cout(solve(1, N, C));
    return 0;
}
accuracy: 0.3548387096774194
time_ms: 60
memory_kb: 6872
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

// =============================================================================
// === BIT Class
// =============================================================================
class BIT {
    public:
    int size_ = 1;
    vector<long long> dat;

    void init(int sz) {
        size_ = sz + 2;
        dat.resize(size_ + 2, 0);
    }

    void add(int pos, long long x) {
        pos += 1;
        while (pos <= size_) {
            dat[pos] += x;
            pos += (pos & -pos);
        }
    }

    long long sum(int pos) {
        pos += 1; long long s = 0;
        while (pos >= 1) {
            s += dat[pos];
            pos -= (pos & -pos);
        }
        return s;
    }
};


// =============================================================================
// === 2D BIT Class
// =============================================================================
class TwoDimensionalBIT {
    public:
    int size_ = 1;
    map<pair<int, int>, long long> dat;

    void init(int sz) {
        size_ = sz + 2;
        dat.clear();
    }

    void add(int p1, int p2, long long x) {
        p1 += 1;
        p2 += 1;
        while (p1 <= size_) {
            int c2 = p2;
            while (c2 <= size_) {
                dat[make_pair(p1, c2)] += x;
                c2 += (c2 & -c2);
            }
            p1 += (p1 & -p1);
        }
    }

    long long sum(int p1, int p2) {
        long long s = 0;
        p1 += 1;
        p2 += 1;
        while (p1 >= 1) {
            int c2 = p2;
            while (c2 >= 1) {
                s += dat[make_pair(p1, c2)];
                c2 -= (c2 & -c2);
            }
            p1 -= (p1 & -p1);
        }
        return s;
    }
};


// =============================================================================
// === Main
// =============================================================================
const long long INF = 10000LL * 10000LL * 10000LL;
long long N;
long long C;
long long B[1 << 17], W[1 << 17], X[1 << 17];
BIT Z1, Z2;
TwoDimensionalBIT Z3;

int main() {
    // Step 1. Input
    cin >> N >> C;
    for (int i = 0; i < N; i++) cin >> B[i] >> W[i];

    // Step 2. Compression
    vector<long long> Zahyou;
    for (int i = 0; i < N; i++) Zahyou.push_back(W[i]);
    sort(Zahyou.begin(), Zahyou.end());
    Zahyou.erase(unique(Zahyou.begin(), Zahyou.end()), Zahyou.end());
    for (int i = 0; i < N; i++) X[i] = lower_bound(Zahyou.begin(), Zahyou.end(), W[i]) - Zahyou.begin();

    // Step 3. Solve 1
    long long ans1 = 0;
    long long ans2 = 0;
    Z1.init(N + 2);
    Z2.init(N + 2);
    for (int i = 0; i < N; i++) {
        ans1 += (Z1.sum(N + 1) - Z1.sum(B[i])) * W[i] * C;
        ans1 += (Z2.sum(N + 1) - Z2.sum(B[i]));
        Z1.add(B[i], 1);
        Z2.add(B[i], W[i]);
    }

    // Step 4. Solve 2
    Z3.init(N + 2);
    for (int i = 0; i < N; i++) {
        long long r = Z3.sum(N - B[i], X[i] - 1);
        long long cnt = r / INF;
        long long sum = r % INF;
        ans2 += (C - 1) * (W[i] * cnt - sum);
        Z3.add(N - B[i], X[i], INF + W[i]);
    }

    // Step 5. Output
    cout << ans1 - ans2 << endl;
    return 0;
}
accuracy: 1
time_ms: 3330
memory_kb: 448448
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

template <typename M, typename N, M (*f)(M, M), M (*g)(M, N), M (*m1)()>
struct SegmentTree {
    int sz, n;
    vector<M> data;
    SegmentTree(int _n = 0) : n(_n) {
        sz = 1;
        while (sz < _n)
            sz <<= 1;
        data.assign(2 * sz, m1());
    }
    void run(vector<M> &v) {
        for (int i = 0; i < (int)v.size(); i++)
            data[i + sz] = v[i];
        for (int k = sz - 1; k > 0; k--)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    void set(int k, const M &x) {
        k += sz;
        data[k] = x;
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    void update(int k, const N &x) {
        k += sz;
        data[k] = g(data[k], x);
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    M query(int a, int b) {
        M L = m1(), R = m1();
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1)
                L = f(L, data[a++]);
            if (b & 1)
                R = f(data[--b], R);
        }
        return f(L, R);
    }
    M operator[](const int &k) const {
        return data[k + sz];
    }
    vector<M> get() {
        return {data.begin() + sz, data.begin() + sz + n};
    }
    template <class F> int max_right(int L, F ch) const {
        int l = sz + L, w = 1;
        M ansL = m1();
        for (; L + w <= sz; l >>= 1, w <<= 1)
            if (l & 1) {
                if (not ch(f(ansL, data[l])))
                    break;
                ansL = f(ansL, data[l++]);
                L += w;
            }
        while (l <<= 1, w >>= 1) {
            if (L + w <= sz && ch(f(ansL, data[l]))) {
                ansL = f(ansL, data[l++]);
                L += w;
            }
        }
        return L;
    }
    template <class F> int min_left(int R, F ch) const {
        int r = sz + R, w = 1;
        M ansR = m1();
        for (; R - w >= 0; r >>= 1, w <<= 1)
            if (r & 1) {
                if (not ch(f(data[r - 1], ansR)))
                    break;
                ansR = f(data[--r], ansR);
                R -= w;
            }
        while (r <<= 1, w >>= 1) {
            if (R - w >= 0 && ch(f(data[r - 1], ansR))) {
                ansR = f(data[--r], ansR);
                R -= w;
            }
        }
        return R;
    }
};

/**
 * @brief Segment Tree
 */

template<typename M,typename N,M (*f)(M,M),M (*g)(M,N),M (*m1)()>struct SegmentTree2D{
    int n;
    vector<SegmentTree<M,N,f,g,m1>> st;
    vector<vector<int>> ys;
    SegmentTree2D(){}
    int id(int x,int y){return lower_bound(ALL(ys[x]),y)-ys[x].begin();}
    using P=pair<int,int>;
    vector<int> xs; vector<P> ps;
    void push(int x,int y){
        ps.push_back({x,y});
    }
    void init(){
        for(auto& [x,y]:ps)xs.push_back(x);
        sort(ALL(xs));
        xs.erase(unique(ALL(xs)),xs.end());
        n=xs.size();
        ys.resize(n*2);
        for(auto& [x,y]:ps){
            int i=lower_bound(ALL(xs),x)-xs.begin();
            for(i+=n;i;i>>=1)ys[i].push_back(y);
        }
        for(int i=0;i<n*2;i++){
            sort(ALL(ys[i]));
            ys[i].erase(unique(ALL(ys[i])),ys[i].end());
            st.push_back(SegmentTree<M,N,f,g,m1>(ys[i].size()));
        }
    }
    void update(int x,int y,N w){
        x=(lower_bound(ALL(xs),x)-xs.begin())+n;
        st[x].update(id(x,y),w);
        M cur=st[x][id(x,y)];
        int pos=x;
        while(x>>=1){
            M opp=st[pos^1].query(id(pos^1,y),id(pos^1,y+1));
            cur=f(cur,opp);
            st[x].set(id(x,y),cur);
            pos>>=1;
        }
    }
    M query(int x0,int x1,int y0,int y1){
        x0=lower_bound(ALL(xs),x0)-xs.begin();
        x1=lower_bound(ALL(xs),x1)-xs.begin();
        M res=m1();
        for(x0+=n,x1+=n;x0<x1;x0>>=1,x1>>=1){
            if(x0&1)res=f(res,st[x0].query(id(x0,y0),id(x0,y1))),x0++;
            if(x1&1)x1--,res=f(res,st[x1].query(id(x1,y0),id(x1,y1)));
        }
        return res;
    }
};

/**
 * @brief 2D Segment Tree
 */

ll f(ll A, ll B) {return A+B;}
ll g(ll A, ll B) {return B;}
ll e() {return 0;}

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    int N;
    ll C;
    cin >> N >> C;
    vector<int> B(N);
    vector<ll> W(N), WS;
    rep(i,0,N) cin >> B[i] >> W[i], B[i]--, WS.push_back(W[i]);
    UNIQUE(WS);
    rep(i,0,N) W[i] = LB(WS,W[i]);
    SegmentTree2D<ll,ll,f,g,e> Seg, Seg2;
    rep(i,0,N) Seg.push(B[i],W[i]), Seg2.push(B[i],W[i]);
    Seg.init(), Seg2.init();
    ll ANS = 0;
    rep(i,0,N) {
        ANS += Seg.query(B[i]+1,N,0,WS.size());
        ANS += Seg2.query(B[i]+1,N,0,WS.size()) * WS[W[i]];
        ANS += Seg.query(B[i]+1,N,0,W[i]) * (C-1);
        ANS += Seg2.query(B[i]+1,N,W[i],WS.size()) * WS[W[i]] * (C-1);
        Seg.update(B[i],W[i],WS[W[i]]);
        Seg2.update(B[i],W[i],1);
    }
    cout << ANS << '\n';
}
accuracy: 1
time_ms: 1550
memory_kb: 119044
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll=long long;
struct fenwick_tree {
    fenwick_tree(int n) : _n(n), data(n) {}
    void add(int p, ll x) {
        p++;
        while (p <= _n) {
            data[p - 1] += x;
            p += p & -p;
        }
    }
    ll sum(int r) {
        ll s = 0;
        while (r > 0) {
            s += data[r - 1];
            r -= r & -r;
        }
        return s;
    }
    ll sum(int l, int r) {
        return sum(r) - sum(l);
    }
    int _n;
    vector<ll> data;
};
ll N,C,an=0;
vector<pair<ll,ll>> P;

fenwick_tree FW(1e5+10);
fenwick_tree FWN(1e5+10);
vector<int> ADD;
void cl(){
    for(auto p:ADD){
        FW.add(p,-FW.sum(p,p+1));
        FWN.add(p,-FWN.sum(p,p+1));
    }
    ADD={};
}
void DAC(int L,int R){
    if(R==L+1)return;
    int mid=(R+L)/2;
    DAC(L,mid);DAC(mid,R);
    
    vector<pair<ll,pair<ll,bool>>> Q;
    for(int i=L;i<R;i++){
        Q.push_back({P[i].first,{P[i].second,i<mid}});
        if(i<mid){
            FW.add(P[i].first,P[i].second);
            FWN.add(P[i].first,1);
            ADD.emplace_back(P[i].first);
        }
        else an+=FW.sum(P[i].first,1e5+4)+FWN.sum(P[i].first,1e5+4)*P[i].second;
    }
    cl();

    sort(Q.begin(),Q.end());
    for(int i=0;i<R-L;i++){
        auto [id,vf]=Q[i];
        auto [v,f]=vf;
        ADD.emplace_back(v);
        if(f) an+=C*v*FW.sum(v+1,1e5+10);
        else FW.add(v,1);

        auto [id2,vf2]=Q[R-L-1-i];
        auto [v2,f2]=vf2;
        ADD.emplace_back(v2);
        if(!f2) an+=C*v2*FWN.sum(v2,1e5+10);
        else FWN.add(v2,1);
    }
    cl();
    return;
}

int main(){
   cin>>N>>C;
   C--;
   P.resize(N);
   for(int i=0;i<N;i++){
    cin>>P[i].first>>P[i].second;
    P[i].first--;
   }
   DAC(0,N);
   cout<<an<<endl;
   
}
accuracy: 1
time_ms: 450
memory_kb: 12796
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll=long long;
struct fenwick_tree {
    fenwick_tree() : _n(0) {}
    explicit fenwick_tree(int n) : _n(n), data(n) {}
    void add(int p, ll x) {
        p++;
        while (p <= _n) {
            data[p - 1] += x;
            p += p & -p;
        }
    }
    ll sum(int r) {
        ll s = 0;
        while (r > 0) {
            s += data[r - 1];
            r -= r & -r;
        }
        return s;
    }
    ll sum(int l, int r) {
        return sum(r) - sum(l);
    }
    int _n;
    vector<ll> data;
};
ll N,C,an=0;
vector<pair<ll,ll>> P;

fenwick_tree FW(1e5+10);
fenwick_tree FWN(1e5+10);
void clear(vector<int> &P){
    for(auto p:P){
        FW.add(p,-FW.sum(p,p+1));
        FWN.add(p,-FWN.sum(p,p+1));
    }
    P={};
}
void DAC(int L,int R){
    if(R==L+1)return;
    int mid=(R+L)/2;
    DAC(L,mid);
    DAC(mid,R);
    
    vector<pair<ll,pair<ll,bool>>> Q;
    vector<int> ADD;
    for(int i=L;i<R;i++){
        Q.push_back({P[i].first,{P[i].second,i<mid}});
        if(i<mid){
            FW.add(P[i].first,P[i].second);
            FWN.add(P[i].first,1);
            ADD.emplace_back(P[i].first);
        }
        else{
            an+=FW.sum(P[i].first,1e5+4);
            an+=FWN.sum(P[i].first,1e5+4)*P[i].second;
        }
    }
    clear(ADD);

    sort(Q.begin(),Q.end());
    for(int i=0;i<R-L;i++){
       auto [id,valflg]=Q[i];
       auto [val,flg]=valflg;
       ADD.emplace_back(val);
       if(flg){
            an+=C*val*FW.sum(val+1,1e5+10);
        }
        else{
            FW.add(val,1);
        }
    }
    for(int i=R-L-1;i>=0;i--){
        auto [id,valflg]=Q[i];
        auto [val,flg]=valflg;
        ADD.emplace_back(val);
        if(flg){
            FWN.add(val,1);
        }
        else{
            an+=C*val*FWN.sum(val,1e5+10);
        }
    }
    clear(ADD);
    return;


}

int main(){
   cin>>N>>C;
   C--;
   P.resize(N);
   for(int i=0;i<N;i++){
    cin>>P[i].first>>P[i].second;
    P[i].first--;
   }
   DAC(0,N);
   cout<<an<<endl;
   
}
accuracy: 1
time_ms: 450
memory_kb: 12000
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;

#include <cassert>
#include <vector>


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

// Reference: https://en.wikipedia.org/wiki/Fenwick_tree
template <class T> struct fenwick_tree {
    using U = internal::to_unsigned_t<T>;

  public:
    fenwick_tree() : _n(0) {}
    explicit fenwick_tree(int n) : _n(n), data(n) {}

    void add(int p, T x) {
        assert(0 <= p && p < _n);
        p++;
        while (p <= _n) {
            data[p - 1] += U(x);
            p += p & -p;
        }
    }

    T sum(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        return sum(r) - sum(l);
    }

  private:
    int _n;
    std::vector<U> data;

    U sum(int r) {
        U s = 0;
        while (r > 0) {
            s += data[r - 1];
            r -= r & -r;
        }
        return s;
    }
};

}  // namespace atcoder

using namespace atcoder;
using ll=long long;
ll N,C,an=0;
vector<pair<ll,ll>> P;

fenwick_tree<ll> FW(1e5+10);
fenwick_tree<ll> FWN(1e5+10);
void clear(vector<int> &P){
    for(auto p:P){
        FW.add(p,-FW.sum(p,p+1));
        FWN.add(p,-FWN.sum(p,p+1));
    }
    P={};
}
void DAC(int L,int R){
    if(R==L+1)return;
    int mid=(R+L)/2;
    DAC(L,mid);
    DAC(mid,R);
    
    vector<pair<ll,pair<ll,bool>>> Q;
    vector<int> ADD;
    for(int i=L;i<R;i++){
        Q.push_back({P[i].first,{P[i].second,i<mid}});
        if(i<mid){
            FW.add(P[i].first,P[i].second);
            FWN.add(P[i].first,1);
            ADD.emplace_back(P[i].first);
        }
        else{
            an+=FW.sum(P[i].first,1e5+4);
            an+=FWN.sum(P[i].first,1e5+4)*P[i].second;
        }
    }
    clear(ADD);

    sort(Q.begin(),Q.end());
    for(int i=0;i<R-L;i++){
       auto [id,valflg]=Q[i];
       auto [val,flg]=valflg;
       ADD.emplace_back(val);
       if(flg){
            an+=C*val*FW.sum(val+1,1e5+10);
        }
        else{
            FW.add(val,1);
        }
    }
    for(int i=R-L-1;i>=0;i--){
        auto [id,valflg]=Q[i];
        auto [val,flg]=valflg;
        ADD.emplace_back(val);
        if(flg){
            FWN.add(val,1);
        }
        else{
            an+=C*val*FWN.sum(val,1e5+10);
        }
    }
    clear(ADD);
    return;


}

int main(){
   cin>>N>>C;
   C--;
   P.resize(N);
   for(int i=0;i<N;i++){
    cin>>P[i].first>>P[i].second;
    P[i].first--;
   }
   DAC(0,N);
   cout<<an<<endl;
   
}
accuracy: 1
time_ms: 460
memory_kb: 11796
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=300005,INF=1<<30;

//2d point update rectangle sum

// https://kopricky.github.io/code/SegmentTrees/rangetree_pointupdate.html

template<typename T> class segtree {
private:
    int n, sz;
    vector<T> node;
public:
    void init(const vector<T>& v){
        sz = (int)v.size();
        n = 1;
        while(n < sz){
            n *= 2;
        }
        node.assign(2*n, 0);
        for(int i = 0; i < sz; i++){
            node[i+n] = v[i];
        }
        for(int i=n-1; i>=1; i--){
            node[i] = node[2*i] + node[2*i+1];
        }
    }
    void update(int k, const T a)
    {
        node[k+=n] += a;
        while(k>>=1){
            node[k] = node[2*k] + node[2*k+1];
        }
    }
    T query(int a, int b)
    {
        T res1 = 0, res2 = 0;
        a += n, b += n;
        while(a != b){
            if(a % 2) res1 = res1 + node[a++];
            if(b % 2) res2 = res2 + node[--b];
            a >>= 1, b >>= 1;
        }
        return res1 + res2;
    }
    void print(){
        for(int i = 0; i < sz; i++){
            cout << query(i, i+1) << " ";
        }
        cout << endl;
    }
};

//座標の型, 値の型
template<typename CandidateType, typename ValueType> class RangeTree
{
public:
    static_assert(std::is_integral<CandidateType>::value, "Integral required.");
private:
    using CT = CandidateType;
    using VT = ValueType;
    using pcc = pair<CT, CT>;
    using pci = pair<CT, int>;
    int n, sz;
    vector<segtree<VT> > seg;
    // y座標, x座標
    vector<vector<pcc> > yx;
    // y座標, x座標
    vector<pcc> sorted;
    void update_(int id, const CT x, const CT y, const VT val) {
        id += n-1;
        const int yid = lower_bound(all(yx[id]), pcc(y, x)) - yx[id].begin();
        seg[id].update(yid, val);
        while(id > 0){
            id = (id - 1) / 2;
            const int yid = lower_bound(all(yx[id]), pcc(y, x)) - yx[id].begin();
            seg[id].update(yid, val);
        }
    }
    VT query(const int lxid, const int rxid, const CT ly, const CT ry, const int k, const int l, const int r) {
        if(r <= lxid || rxid <= l) return 0;
        if(lxid <= l && r <= rxid){
            const int lyid = lower_bound(all(yx[k]), pcc(ly, numeric_limits<CT>::min())) - yx[k].begin();
            const int ryid = upper_bound(all(yx[k]), pcc(ry, numeric_limits<CT>::min())) - yx[k].begin();
            return (lyid >= ryid) ? 0 : seg[k].query(lyid, ryid);
        }else{
            return query(lxid, rxid, ly, ry, 2*k+1, l, (l+r)/2) + query(lxid, rxid, ly, ry, 2*k+2, (l+r)/2, r);
        }
    }
public:
    // 座標, 点の値
    RangeTree(const vector<pcc>& cand, const vector<VT>& val) : n(1), sz((int)cand.size()), sorted(sz){
        while(n < sz) n *= 2;
        for(int i = 0; i < sz; ++i){
            sorted[i] = {cand[i].first, i};
        }
        sort(all(sorted), [&](const pcc& a, const pcc& b){
            return (a.first == b.first) ? (cand[a.second].second < cand[b.second].second) : (a.first < b.first);
        });
        yx.resize(2*n-1), seg.resize(2*n-1);
        for(int i = 0; i < sz; ++i){
            yx[i+n-1] = {{sorted[i].second, sorted[i].first}};
            vector<VT> arg = {val[sorted[i].second]};
            seg[i+n-1].init(arg);
            sorted[i].second = cand[sorted[i].second].second;
        }
        for(int i = n-2; i >= 0; --i){
            yx[i].resize((int)yx[2*i+1].size() + (int)yx[2*i+2].size());
            if(yx[i].empty()) continue;
            merge(all(yx[2*i+1]), all(yx[2*i+2]), yx[i].begin(), [&](const pcc& a, const pcc& b){
                return (cand[a.first].second == cand[b.first].second)
                ? (a.second < b.second) : (cand[a.first].second < cand[b.first].second);
            });
            vector<VT> arg((int)yx[i].size());
            for(int j = 0; j < (int)yx[i].size(); ++j){
                arg[j] = val[yx[i][j].first];
            }
            seg[i].init(arg);
        }
        for(int i = 0; i < 2*n-1; ++i){
            for(pcc& e : yx[i]){
                e.first = cand[e.first].second;
            }
        }
    }
    // 点 (x,y) の更新を行う
    void update(const CT x, const CT y, const VT val){
        const int id = lower_bound(all(sorted), pcc(x, y)) - sorted.begin();
        return update_(id, x, y, val);
    }
    // [lx,rx) × [ly,ry) の長方形領域のクエリに答える
    VT query(const CT lx, const CT ly, const CT rx, const CT ry){
        const int lxid = lower_bound(all(sorted), pcc(lx, numeric_limits<CT>::min())) - sorted.begin();
        const int rxid = upper_bound(all(sorted), pcc(rx, numeric_limits<CT>::min())) - sorted.begin();
        return (lxid >= rxid) ? 0 : query(lxid, rxid, ly, ry, 0, 0, n);
    }
};

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    ll N,C;cin>>N>>C;
    vector<pair<ll,ll>> S(N);
    vector<ll> T(N);
    for(int i=0;i<N;i++){
        int x;cin>>x;x--;
        int y;cin>>y;
        S[i]=mp(x,y);
    }
    
    RangeTree<ll,ll> RT(S,T),CN(S,T);
    
    ll ans=0;
    
    for(auto [x,y]:S){
        ll a=CN.query(x,y,N,100003);
        ans+=y*a*C;
        ll b=CN.query(x,0,N,y);
        ans+=y*b;
        ll c=RT.query(x,0,N,y);
        ans+=c*C;
        ll d=RT.query(x,y,N,100003);
        ans+=d;
        
        RT.update(x,y,y);
        CN.update(x,y,1);
    }
    
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 1530
memory_kb: 165684
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
#define all(p) p.begin(),p.end()

int main(){
	ll N,C;
	cin>>N>>C;
	vector<ll> B(N),W(N);
	rep(i,0,N) cin>>B[i]>>W[i],B[i]--;
	vector<ll> w_order(N);
	iota(w_order.begin(),w_order.end(),0);
	sort(all(w_order),[&](int l,int r){
		return W[l]<W[r];
	});
	ll D=min(N,100ll);
	vector<int> pos(N);
	vector<int> L(D+1);
	rep(i,0,D+1){
		L[i]=(N*i+D-1)/D;
	}
	rep(i,0,N){
		int tmp=(i*D)/N;
		pos[w_order[i]]=tmp;
	}
	vector<vector<int>> A(D);
	vector<vector<int>> count(D);
	vector<vector<int>> sum(D);
	rep(i,0,N){
		A[pos[i]].push_back(B[i]);
	}
	rep(i,0,D){
		sort(all(A[i]));
		count[i].resize(A[i].size()+1,0);
		sum[i].resize(A[i].size()+1,0);
	}
	ll ans=0;
	rep(i,0,D){
		rep(k,L[i],L[i+1]) rep(l,k+1,L[i+1]){
			int a=w_order[k],b=w_order[l];
			if((a<b)^(B[a]<B[b])){
				ans+=C*W[a];
				ans+=W[b];
			}
		}
	}
	rep(i,0,N){
		rep(j,0,D){
			if(j==pos[i]) continue;
			int ind=lower_bound(A[j].begin(),A[j].end(),B[i])-A[j].begin();
			if(j<pos[i]){
				ans+=sum[j][ind]*C;
				ans+=count[j][ind]*W[i];
			}else{
				ans+=sum[j][ind];
				ans+=count[j][ind]*W[i]*C;
			}
		}
		rep(k,0,(int)(A[pos[i]].size())){
			sum[pos[i]][k]+=W[i];
			count[pos[i]][k]++;
			if(A[pos[i]][k]==B[i]) break;
		}
	}
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 710
memory_kb: 7040
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
template<class T> bool chmin(T &a,const T b){if(a>b){a=b;return 1;}return 0;}
template<class T> bool chmax(T &a,const T b){if(a<b){a=b;return 1;}return 0;}
const int INF = (1<<30)-1;
const ll  ILL = 1e15;
#define all(p) p.begin(),p.end()
const int mod=998244353;
using ld = long double;

/*

任意の l<rについて、
p_{l}>p_{r}
を満たすものの、
C*max(w_l,w_r)+min(w_l,w_r)
の総和

i*D/N>=a
i>=(N*a)/D
i=(N*a+D-1)/D

*/

int main(){
	ll N,C;
	cin>>N>>C;
	vector<ll> B(N),W(N);
	rep(i,0,N) cin>>B[i]>>W[i],B[i]--;
	vector<ll> w_order(N);
	iota(w_order.begin(),w_order.end(),0);
	sort(all(w_order),[&](int l,int r){
		return W[l]<W[r];
	});
	ll D=min(N,321ll);
	vector<ll> S(D);
	vector<int> pos(N);
	vector<int> L(D+1);
	rep(i,0,D+1){
		L[i]=(N*i+D-1)/D;
	}
	rep(i,0,N){
		int tmp=(i*D)/N;
		pos[w_order[i]]=tmp;
		S[tmp]++;
	}
	vector<vector<int>> A(D);
	vector<vector<int>> count(D);
	vector<vector<int>> sum(D);
	rep(i,0,N){
		A[pos[i]].push_back(B[i]);
	}
	rep(i,0,D){
		sort(all(A[i]));
		count[i].resize(S[i]+1,0);
		sum[i].resize(S[i]+1,0);
	}
	ll ans=0;
	rep(i,0,D){
		rep(k,L[i],L[i+1]) rep(l,k+1,L[i+1]){
			int a=w_order[k],b=w_order[l];
			if((a<b)^(B[a]<B[b])){
				ans+=C*W[a];
				ans+=W[b];
			}
		}
	}
	rep(i,0,N){
		rep(j,0,D){
			if(j==pos[i]) continue;
			int ind=lower_bound(A[j].begin(),A[j].end(),B[i])-A[j].begin();
			if(j<pos[i]){
				ans+=sum[j][ind]*C;
				ans+=count[j][ind]*W[i];
			}else{
				ans+=sum[j][ind];
				ans+=count[j][ind]*W[i]*C;
			}
		}
		rep(k,0,S[pos[i]]){
			sum[pos[i]][k]+=W[i];
			count[pos[i]][k]++;
			if(A[pos[i]][k]==B[i]) break;
		}
	}
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 1120
memory_kb: 7260
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long

template <typename T>
class AVL {
    int s = 0;
    struct node {
        T val;
        node *ch[2];
        int dep, size;
        node(T v, node *l = nullptr, node *r = nullptr) : val(v), dep(1), size(1) {
            ch[0] = l;
            ch[1] = r;
        }
    };
    int depth(node *t) { return t == nullptr ? 0 : t->dep; }
    int count(node *t) { return t == nullptr ? 0 : t->size; }
    node *update(node *t) {
        t->dep = max(depth(t->ch[0]), depth(t->ch[1])) + 1;
        t->size = count(t->ch[0]) + count(t->ch[1]) + 1;
        return t;
    }
    node *rotate(node *t, int b) {
        node *s = t->ch[1 - b];
        t->ch[1 - b] = s->ch[b];
        s->ch[b] = t;
        t = update(t);
        s = update(s);
        return s;
    }
    node *fetch(node *t) {
        if (t == nullptr) return t;
        if (depth(t->ch[0]) - depth(t->ch[1]) == 2) {
            if (depth(t->ch[0]->ch[1]) > depth(t->ch[0]->ch[0])) {
                t->ch[0] = rotate(t->ch[0], 0);
            }
            t = rotate(t, 1);
        } else if (depth(t->ch[0]) - depth(t->ch[1]) == -2) {
            if (depth(t->ch[1]->ch[0]) > depth(t->ch[1]->ch[1])) {
                t->ch[1] = rotate(t->ch[1], 1);
            }
            t = rotate(t, 0);
        }
        return t;
    }
    node *insert(node *t, int k, T v) {
        if (t == nullptr) return new node(v);
        int c = count(t->ch[0]), b = (k > c);
        t->ch[b] = insert(t->ch[b], k - (b ? (c + 1) : 0), v);
        update(t);
        return fetch(t);
    }
    node *erase(node *t) {
        if (t == nullptr) return nullptr;
        if (t->ch[0] == nullptr && t->ch[1] == nullptr) {
            delete t;
            return nullptr;
        }
        if (t->ch[0] == nullptr || t->ch[1] == nullptr) {
            node *res = t->ch[t->ch[0] == nullptr];
            delete t;
            return res;
        }
        node *res = new node(find(t->ch[1], 0)->val, t->ch[0], erase(t->ch[1], 0));
        delete t;
        return fetch(update(res));
    }
    node *erase(node *t, int k) {
        if (t == nullptr) return nullptr;
        int c = count(t->ch[0]);
        if (k < c) {
            t->ch[0] = erase(t->ch[0], k);
            t = update(t);
        } else if (k > c) {
            t->ch[1] = erase(t->ch[1], k - (c + 1));
            t = update(t);
        } else {
            t = erase(t);
        }
        return fetch(t);
    }
    node *find(node *t, int k) {
        if (t == nullptr) return t;
        int c = count(t->ch[0]);
        return k < c ? find(t->ch[0], k) : k == c ? t : find(t->ch[1], k - (c + 1));
    }
    int cnt(node *t, T v) {
        if (t == nullptr) return 0;
        if (t->val < v) return count(t->ch[0]) + 1 + cnt(t->ch[1], v);
        if (t->val == v) return count(t->ch[0]);
        return cnt(t->ch[0], v);
    }
    node *root;

public:
    AVL() : root(nullptr) {}
    void insert(T val) {
        root = insert(root, cnt(root, val), val);
        s++;
    }

    // 0-indexed
    T get_kth_small(int k) {
        assert(k < s);
        return find(root, k)->val;
    }
    // 0-indexed
    void erase_kth_small(int k) {
        assert(k < s);
        root = erase(root, k);
        s--;
    }

    // 0-indexed
    T get_kth_big(int k) {
        assert(k < s);
        return get_kth_small(s - 1 - k);
    }
    // 0-indexed
    void erase_kth_big(int k) {
        assert(k < s);
        erase_kth_small(s - 1 - k);
    }

    int count(T val) { return cnt(root, val); }
    int size() { return s; }
    bool empty() { return s == 0; }

    int count_lt(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_small(m) < val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int count_le(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_small(m) <= val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int count_gt(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_big(m) > val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int count_ge(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_big(m) >= val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }

    void erase(T val) {
        int kth = count_lt(val);
        assert(get_kth_small(kth) == val);
        erase_kth_small(kth);
    }
};

class xorshift {
    uint64_t x;

public:
    xorshift() {
        mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
        x = rnd();
        for (int i = 0; i < 100; i++) {
            random();
        }
    }

    uint64_t random() {
        x = x ^ (x << 7);
        return x = x ^ (x >> 9);
    }
};

using T = long long;

struct SumMonoid {
    static constexpr T id() { return 0; }

    static T op(T a, T b) { return a + b; }
};

struct MinMonoid {
    static constexpr T id() { return 2e18; }

    static T op(T a, T b) { return min(a, b); }
};

// 本来はSumMonoid用
struct UpdateMonoid {
    static constexpr T id() { return 2e18; }

    static T op(T a, T b) { return b; }
};

struct Modifier {
    // lazyの結果によってaccがどう変わるか。szは部分木のサイズ
    static T op(T a, T b, int sz) { return b == UpdateMonoid::id() ? a : b * sz; }
};

template <class Monoid, class OperatorMonoid>
class ImplicitTreap {
    xorshift rnd;

    struct Node {
        T value, acc, lazy;
        int priority, cnt;
        bool rev;
        Node *l, *r;

        Node(T value, int priority)
            : value(value),
              acc(Monoid::id()),
              lazy(OperatorMonoid::id()),
              priority(priority),
              cnt(1),
              rev(false),
              l(nullptr),
              r(nullptr) {}
    } *root = nullptr;

    using Tree = Node *;

    int cnt(Tree t) { return t ? t->cnt : 0; }

    T acc(Tree t) { return t ? t->acc : Monoid::id(); }

    void update_cnt(Tree t) {
        if (t) {
            t->cnt = 1 + cnt(t->l) + cnt(t->r);
        }
    }

    void update_acc(Tree t) {
        if (t) {
            t->acc = Monoid::op(acc(t->l), Monoid::op(t->value, acc(t->r)));
        }
    }

    void pushup(Tree t) { update_cnt(t), update_acc(t); }

    void pushdown(Tree t) {
        if (t && t->rev) {
            t->rev = false;
            swap(t->l, t->r);
            if (t->l) t->l->rev ^= 1;
            if (t->r) t->r->rev ^= 1;
        }
        if (t && t->lazy != OperatorMonoid::id()) {
            if (t->l) {
                t->l->lazy = OperatorMonoid::op(t->l->lazy, t->lazy);
                t->l->acc = Modifier::op(t->l->acc, t->lazy, cnt(t->l));
            }
            if (t->r) {
                t->r->lazy = OperatorMonoid::op(t->r->lazy, t->lazy);
                t->r->acc = Modifier::op(t->r->acc, t->lazy, cnt(t->r));
            }
            t->value = Modifier::op(t->value, t->lazy, 1);
            t->lazy = OperatorMonoid::id();
        }
        pushup(t);
    }

    void split(Tree t, int key, Tree &l, Tree &r) {
        if (!t) {
            l = r = nullptr;
            return;
        }
        pushdown(t);
        int implicit_key = cnt(t->l) + 1;
        if (key < implicit_key) {
            split(t->l, key, l, t->l), r = t;
        } else {
            split(t->r, key - implicit_key, t->r, r), l = t;
        }
        pushup(t);
    }

    void insert(Tree &t, int key, Tree item) {
        Tree t1, t2;
        split(t, key, t1, t2);
        merge(t1, t1, item);
        merge(t, t1, t2);
    }

    void merge(Tree &t, Tree l, Tree r) {
        pushdown(l);
        pushdown(r);
        if (!l || !r) {
            t = l ? l : r;
        } else if (l->priority > r->priority) {
            merge(l->r, l->r, r), t = l;
        } else {
            merge(r->l, l, r->l), t = r;
        }
        pushup(t);
    }

    void erase(Tree &t, int key) {
        Tree t1, t2, t3;
        split(t, key + 1, t1, t2);
        split(t1, key, t1, t3);
        merge(t, t1, t2);
    }

    void update(Tree t, int l, int r, T x) {
        if (l >= r) return;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        t2->lazy = OperatorMonoid::op(t2->lazy, x);
        t2->acc = Modifier::op(t2->acc, x, cnt(t2));
        merge(t2, t2, t3);
        merge(t, t1, t2);
    }

    T query(Tree t, int l, int r) {
        if (l == r) return Monoid::id();
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        T ret = t2->acc;
        merge(t2, t2, t3);
        merge(t, t1, t2);
        return ret;
    }

    // [l, r)の中で左から何番目か
    int find(Tree t, T x, int offset, bool left = true) {
        if (Monoid::op(t->acc, x) == x) {
            return -1;
        } else {
            if (left) {
                if (t->l && Monoid::op(t->l->acc, x) != x) {
                    return find(t->l, x, offset, left);
                } else {
                    return (Monoid::op(t->value, x) != x) ? offset + cnt(t->l)
                                                          : find(t->r, x, offset + cnt(t->l) + 1, left);
                }
            } else {
                if (t->r && Monoid::op(t->r->acc, x) != x) {
                    return find(t->r, x, offset + cnt(t->l) + 1, left);
                } else {
                    return (Monoid::op(t->value, x) != x) ? offset + cnt(t->l) : find(t->l, x, offset, left);
                }
            }
        }
    }

    void reverse(Tree t, int l, int r) {
        if (l > r) return;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        t2->rev ^= 1;
        merge(t2, t2, t3);
        merge(t, t1, t2);
    }

    // [l, r)の先頭がmになるようにシフトさせる。std::rotateと同じ仕様
    void rotate(Tree t, int l, int m, int r) {
        reverse(t, l, r);
        reverse(t, l, l + r - m);
        reverse(t, l + r - m, r);
    }

    void dump(Tree t) {
        if (!t) return;
        pushdown(t);
        dump(t->l);
        cout << t->value << " ";
        dump(t->r);
    }

public:
    ImplicitTreap() {}

    ImplicitTreap(vector<T> as) {
        ::reverse(as.begin(), as.end());
        for (T a : as) {
            insert(0, a);
        }
    }

    int size() { return cnt(root); }

    void insert(int pos, T x) { insert(root, pos, new Node(x, rnd.random())); }

    void update(int l, int r, T x) { update(root, l, r, x); }

    T query(int l, int r) { return query(root, l, r); }

    // 二分探索。[l, r)内のkでMonoid::op(tr[k], x) != xとなる最左/最右のもの。存在しない場合は-1
    // たとえばMinMonoidの場合、x未満の最左/最右の要素の位置を返す
    int binary_search(int l, int r, T x, bool left = true) {
        if (l >= r) return -1;
        Tree t1, t2, t3;
        split(root, l, t1, t2);
        split(t2, r - l, t2, t3);
        int ret = find(t2, x, l, left);
        merge(t2, t2, t3);
        merge(root, t1, t2);
        return ret;
    }

    void erase(int pos) { erase(root, pos); }

    void reverse(int l, int r) { reverse(root, l, r); }

    void rotate(int l, int m, int r) { rotate(root, l, m, r); }

    void dump() {
        dump(root);
        cout << endl;
    }

    T operator[](int pos) { return query(pos, pos + 1); }
};

struct PrioritySum {
    ImplicitTreap<SumMonoid, UpdateMonoid> tr;
    ImplicitTreap<MinMonoid, UpdateMonoid> tr2;
    int cnt = 0;

    void add(T a) {
        int p = tr2.binary_search(0, tr2.size(), a);
        if (p == -1) {
            tr.insert(tr.size(), a);
            tr2.insert(tr2.size(), a);
        } else {
            tr.insert(p, a);
            tr2.insert(p, a);
        }
        cnt++;
    }

    void erase_at(int k) {
        assert(0 <= k && k < cnt);
        tr.erase(k);
        tr2.erase(k);
        cnt--;
    }

    int size() const { return cnt; }

    T sum(int k) { return tr.query(0, k); }

    T operator[](int k) { return tr[k]; }

    void dump() { tr.dump(); }
};

long long mergecount(vector<pair<int, int>> &as, int c) {
    long long ret = 0;
    int n = as.size();
    if (n > 1) {
        vector<pair<int, int>> bs(as.begin(), as.begin() + n / 2);
        vector<pair<int, int>> cs(as.begin() + n / 2, as.end());
        ret += mergecount(bs, c);
        ret += mergecount(cs, c);
        AVL<int> avl;
        PrioritySum psum;
        int allcnt = 0;
        long long allsum = 0;
        for (auto &b : bs) {
            avl.insert(b.second);
            psum.add(b.second);
            allcnt++;
            allsum += b.second;
        }

        for (int i = 0, j = 0, k = 0; i < n; i++) {
            if (k == cs.size()) {
                as[i] = bs[j++];
            } else if (j == bs.size()) {
                as[i] = cs[k++];
            } else if (bs[j] <= cs[k]) {
                int w = bs[j].second;
                as[i] = bs[j++];
                assert(psum[avl.count_gt(w)] == w);
                psum.erase_at(avl.count_gt(w));
                avl.erase(w);
                allcnt--;
                allsum -= w;
            } else {
                int w = cs[k].second;
                as[i] = cs[k++];

                int ge_cnt = avl.count_ge(w);
                long long cost = 0;
                cost += psum.sum(ge_cnt) + 1LL * w * c * ge_cnt;
                cost += (allsum - psum.sum(ge_cnt)) * c + 1LL * w * (allcnt - ge_cnt);

                ret += cost;
            }
        }
    }
    return ret;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, c;
    cin >> n >> c;
    vector<pair<int, int>> as;
    for (int i = 0; i < n; i++) {
        int a, b;
        cin >> a >> b;
        as.emplace_back(a, b);
    }

    cout << mergecount(as, c) << endl;
}
accuracy: 1
time_ms: 3550
memory_kb: 138180
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <typename T>
class AVL {
    int s = 0;
    struct node {
        T val;
        node *ch[2];
        int dep, size;
        node(T v, node *l = nullptr, node *r = nullptr) : val(v), dep(1), size(1) {
            ch[0] = l;
            ch[1] = r;
        }
    };
    int depth(node *t) { return t == nullptr ? 0 : t->dep; }
    int count(node *t) { return t == nullptr ? 0 : t->size; }
    node *update(node *t) {
        t->dep = max(depth(t->ch[0]), depth(t->ch[1])) + 1;
        t->size = count(t->ch[0]) + count(t->ch[1]) + 1;
        return t;
    }
    node *rotate(node *t, int b) {
        node *s = t->ch[1 - b];
        t->ch[1 - b] = s->ch[b];
        s->ch[b] = t;
        t = update(t);
        s = update(s);
        return s;
    }
    node *fetch(node *t) {
        if (t == nullptr) return t;
        if (depth(t->ch[0]) - depth(t->ch[1]) == 2) {
            if (depth(t->ch[0]->ch[1]) > depth(t->ch[0]->ch[0])) {
                t->ch[0] = rotate(t->ch[0], 0);
            }
            t = rotate(t, 1);
        } else if (depth(t->ch[0]) - depth(t->ch[1]) == -2) {
            if (depth(t->ch[1]->ch[0]) > depth(t->ch[1]->ch[1])) {
                t->ch[1] = rotate(t->ch[1], 1);
            }
            t = rotate(t, 0);
        }
        return t;
    }
    node *insert(node *t, int k, T v) {
        if (t == nullptr) return new node(v);
        int c = count(t->ch[0]), b = (k > c);
        t->ch[b] = insert(t->ch[b], k - (b ? (c + 1) : 0), v);
        update(t);
        return fetch(t);
    }
    node *erase(node *t) {
        if (t == nullptr) return nullptr;
        if (t->ch[0] == nullptr && t->ch[1] == nullptr) {
            delete t;
            return nullptr;
        }
        if (t->ch[0] == nullptr || t->ch[1] == nullptr) {
            node *res = t->ch[t->ch[0] == nullptr];
            delete t;
            return res;
        }
        node *res = new node(find(t->ch[1], 0)->val, t->ch[0], erase(t->ch[1], 0));
        delete t;
        return fetch(update(res));
    }
    node *erase(node *t, int k) {
        if (t == nullptr) return nullptr;
        int c = count(t->ch[0]);
        if (k < c) {
            t->ch[0] = erase(t->ch[0], k);
            t = update(t);
        } else if (k > c) {
            t->ch[1] = erase(t->ch[1], k - (c + 1));
            t = update(t);
        } else {
            t = erase(t);
        }
        return fetch(t);
    }
    node *find(node *t, int k) {
        if (t == nullptr) return t;
        int c = count(t->ch[0]);
        return k < c ? find(t->ch[0], k) : k == c ? t : find(t->ch[1], k - (c + 1));
    }
    int cnt(node *t, T v) {
        if (t == nullptr) return 0;
        if (t->val < v) return count(t->ch[0]) + 1 + cnt(t->ch[1], v);
        if (t->val == v) return count(t->ch[0]);
        return cnt(t->ch[0], v);
    }
    node *root;

public:
    AVL() : root(nullptr) {}
    void insert(T val) {
        root = insert(root, cnt(root, val), val);
        s++;
    }

    // 0-indexed
    T get_kth_small(int k) {
        assert(k < s);
        return find(root, k)->val;
    }
    // 0-indexed
    void erase_kth_small(int k) {
        assert(k < s);
        root = erase(root, k);
        s--;
    }

    // 0-indexed
    T get_kth_big(int k) {
        assert(k < s);
        return get_kth_small(s - 1 - k);
    }
    // 0-indexed
    void erase_kth_big(int k) {
        assert(k < s);
        erase_kth_small(s - 1 - k);
    }

    int count(T val) { return cnt(root, val); }
    int size() { return s; }
    bool empty() { return s == 0; }

    int count_lt(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_small(m) < val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int count_le(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_small(m) <= val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int count_gt(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_big(m) > val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int count_ge(T val) {
        int l = -1, r = s;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (get_kth_big(m) >= val) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }

    void erase(T val) {
        int kth = count_lt(val);
        assert(get_kth_small(kth) == val);
        erase_kth_small(kth);
    }
};

class xorshift {
    uint64_t x;

public:
    xorshift() {
        mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
        x = rnd();
        for (int i = 0; i < 100; i++) {
            random();
        }
    }

    uint64_t random() {
        x = x ^ (x << 7);
        return x = x ^ (x >> 9);
    }
};

using T = long long;

struct SumMonoid {
    static constexpr T id() { return 0; }

    static T op(T a, T b) { return a + b; }
};

struct MinMonoid {
    static constexpr T id() { return 2e18; }

    static T op(T a, T b) { return min(a, b); }
};

// 本来はSumMonoid用
struct UpdateMonoid {
    static constexpr T id() { return 2e18; }

    static T op(T a, T b) { return b; }
};

struct Modifier {
    // lazyの結果によってaccがどう変わるか。szは部分木のサイズ
    static T op(T a, T b, int sz) { return b == UpdateMonoid::id() ? a : b * sz; }
};

template <class Monoid, class OperatorMonoid>
class ImplicitTreap {
    xorshift rnd;

    struct Node {
        T value, acc, lazy;
        int priority, cnt;
        bool rev;
        Node *l, *r;

        Node(T value, int priority)
            : value(value),
              acc(Monoid::id()),
              lazy(OperatorMonoid::id()),
              priority(priority),
              cnt(1),
              rev(false),
              l(nullptr),
              r(nullptr) {}
    } *root = nullptr;

    using Tree = Node *;

    int cnt(Tree t) { return t ? t->cnt : 0; }

    T acc(Tree t) { return t ? t->acc : Monoid::id(); }

    void update_cnt(Tree t) {
        if (t) {
            t->cnt = 1 + cnt(t->l) + cnt(t->r);
        }
    }

    void update_acc(Tree t) {
        if (t) {
            t->acc = Monoid::op(acc(t->l), Monoid::op(t->value, acc(t->r)));
        }
    }

    void pushup(Tree t) { update_cnt(t), update_acc(t); }

    void pushdown(Tree t) {
        if (t && t->rev) {
            t->rev = false;
            swap(t->l, t->r);
            if (t->l) t->l->rev ^= 1;
            if (t->r) t->r->rev ^= 1;
        }
        if (t && t->lazy != OperatorMonoid::id()) {
            if (t->l) {
                t->l->lazy = OperatorMonoid::op(t->l->lazy, t->lazy);
                t->l->acc = Modifier::op(t->l->acc, t->lazy, cnt(t->l));
            }
            if (t->r) {
                t->r->lazy = OperatorMonoid::op(t->r->lazy, t->lazy);
                t->r->acc = Modifier::op(t->r->acc, t->lazy, cnt(t->r));
            }
            t->value = Modifier::op(t->value, t->lazy, 1);
            t->lazy = OperatorMonoid::id();
        }
        pushup(t);
    }

    void split(Tree t, int key, Tree &l, Tree &r) {
        if (!t) {
            l = r = nullptr;
            return;
        }
        pushdown(t);
        int implicit_key = cnt(t->l) + 1;
        if (key < implicit_key) {
            split(t->l, key, l, t->l), r = t;
        } else {
            split(t->r, key - implicit_key, t->r, r), l = t;
        }
        pushup(t);
    }

    void insert(Tree &t, int key, Tree item) {
        Tree t1, t2;
        split(t, key, t1, t2);
        merge(t1, t1, item);
        merge(t, t1, t2);
    }

    void merge(Tree &t, Tree l, Tree r) {
        pushdown(l);
        pushdown(r);
        if (!l || !r) {
            t = l ? l : r;
        } else if (l->priority > r->priority) {
            merge(l->r, l->r, r), t = l;
        } else {
            merge(r->l, l, r->l), t = r;
        }
        pushup(t);
    }

    void erase(Tree &t, int key) {
        Tree t1, t2, t3;
        split(t, key + 1, t1, t2);
        split(t1, key, t1, t3);
        merge(t, t1, t2);
    }

    void update(Tree t, int l, int r, T x) {
        if (l >= r) return;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        t2->lazy = OperatorMonoid::op(t2->lazy, x);
        t2->acc = Modifier::op(t2->acc, x, cnt(t2));
        merge(t2, t2, t3);
        merge(t, t1, t2);
    }

    T query(Tree t, int l, int r) {
        if (l == r) return Monoid::id();
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        T ret = t2->acc;
        merge(t2, t2, t3);
        merge(t, t1, t2);
        return ret;
    }

    // [l, r)の中で左から何番目か
    int find(Tree t, T x, int offset, bool left = true) {
        if (Monoid::op(t->acc, x) == x) {
            return -1;
        } else {
            if (left) {
                if (t->l && Monoid::op(t->l->acc, x) != x) {
                    return find(t->l, x, offset, left);
                } else {
                    return (Monoid::op(t->value, x) != x) ? offset + cnt(t->l)
                                                          : find(t->r, x, offset + cnt(t->l) + 1, left);
                }
            } else {
                if (t->r && Monoid::op(t->r->acc, x) != x) {
                    return find(t->r, x, offset + cnt(t->l) + 1, left);
                } else {
                    return (Monoid::op(t->value, x) != x) ? offset + cnt(t->l) : find(t->l, x, offset, left);
                }
            }
        }
    }

    void reverse(Tree t, int l, int r) {
        if (l > r) return;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        t2->rev ^= 1;
        merge(t2, t2, t3);
        merge(t, t1, t2);
    }

    // [l, r)の先頭がmになるようにシフトさせる。std::rotateと同じ仕様
    void rotate(Tree t, int l, int m, int r) {
        reverse(t, l, r);
        reverse(t, l, l + r - m);
        reverse(t, l + r - m, r);
    }

    void dump(Tree t) {
        if (!t) return;
        pushdown(t);
        dump(t->l);
        cout << t->value << " ";
        dump(t->r);
    }

public:
    ImplicitTreap() {}

    ImplicitTreap(vector<T> as) {
        ::reverse(as.begin(), as.end());
        for (T a : as) {
            insert(0, a);
        }
    }

    int size() { return cnt(root); }

    void insert(int pos, T x) { insert(root, pos, new Node(x, rnd.random())); }

    void update(int l, int r, T x) { update(root, l, r, x); }

    T query(int l, int r) { return query(root, l, r); }

    // 二分探索。[l, r)内のkでMonoid::op(tr[k], x) != xとなる最左/最右のもの。存在しない場合は-1
    // たとえばMinMonoidの場合、x未満の最左/最右の要素の位置を返す
    int binary_search(int l, int r, T x, bool left = true) {
        if (l >= r) return -1;
        Tree t1, t2, t3;
        split(root, l, t1, t2);
        split(t2, r - l, t2, t3);
        int ret = find(t2, x, l, left);
        merge(t2, t2, t3);
        merge(root, t1, t2);
        return ret;
    }

    void erase(int pos) { erase(root, pos); }

    void reverse(int l, int r) { reverse(root, l, r); }

    void rotate(int l, int m, int r) { rotate(root, l, m, r); }

    void dump() {
        dump(root);
        cout << endl;
    }

    T operator[](int pos) { return query(pos, pos + 1); }
};

struct PrioritySum {
    ImplicitTreap<SumMonoid, UpdateMonoid> tr;
    ImplicitTreap<MinMonoid, UpdateMonoid> tr2;
    int cnt = 0;

    void add(T a) {
        int p = tr2.binary_search(0, tr2.size(), a);
        if (p == -1) {
            tr.insert(tr.size(), a);
            tr2.insert(tr2.size(), a);
        } else {
            tr.insert(p, a);
            tr2.insert(p, a);
        }
        cnt++;
    }

    void erase_at(int k) {
        assert(0 <= k && k < cnt);
        tr.erase(k);
        tr2.erase(k);
        cnt--;
    }

    int size() const { return cnt; }

    T sum(int k) { return tr.query(0, k); }

    T operator[](int k) { return tr[k]; }

    void dump() { tr.dump(); }
};

long long mergecount(vector<pair<int, int>> &as, int c) {
    long long ret = 0;
    int n = as.size();
    if (n > 1) {
        vector<pair<int, int>> bs(as.begin(), as.begin() + n / 2);
        vector<pair<int, int>> cs(as.begin() + n / 2, as.end());
        ret += mergecount(bs, c);
        ret += mergecount(cs, c);
        AVL<int> avl;
        PrioritySum psum;
        int allcnt = 0;
        long long allsum = 0;
        for (auto &b : bs) {
            avl.insert(b.second);
            psum.add(b.second);
            allcnt++;
            allsum += b.second;
        }

        for (int i = 0, j = 0, k = 0; i < n; i++) {
            if (k == cs.size()) {
                as[i] = bs[j++];
            } else if (j == bs.size()) {
                as[i] = cs[k++];
            } else if (bs[j] <= cs[k]) {
                int w = bs[j].second;
                as[i] = bs[j++];
                assert(psum[avl.count_gt(w)] == w);
                psum.erase_at(avl.count_gt(w));
                avl.erase(w);
                allcnt--;
                allsum -= w;
            } else {
                int w = cs[k].second;
                as[i] = cs[k++];

                int ge_cnt = avl.count_ge(w);
                long long cost = 0;
                cost += psum.sum(ge_cnt) + 1LL * w * c * ge_cnt;
                cost += (allsum - psum.sum(ge_cnt)) * c + w * (allcnt - ge_cnt);

                ret += cost;
            }
        }
    }
    return ret;
}

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

    int n, c;
    cin >> n >> c;
    vector<pair<int, int>> as;
    for (int i = 0; i < n; i++) {
        int a, b;
        cin >> a >> b;
        as.emplace_back(a, b);
    }

    cout << mergecount(as, c) << endl;
}
accuracy: 0.3548387096774194
time_ms: 3150
memory_kb: 101876
final_rank: 16

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100005


enum Type{
	COUNT,
	WEIGHT,
};

struct Info{
	int index;
	ll weight;
};

int N;
ll C,BIT[NUM][2];
Info info[NUM];

void add(ll loc,ll value,Type type, ll maximum){

	BIT[loc][type] += value;

	loc += loc & -loc;

	while(loc <= maximum){

		BIT[loc][type] += value;
		loc += loc & -loc;
	}
}

ll getSum(ll loc,Type type){

	ll sum = BIT[loc][type];

	loc -= loc & -loc;

	while(loc > 0){
		sum += BIT[loc][type];
		loc -= loc & -loc;
	}
	return sum;
}

ll calc(ll left,ll right,Type type){
	return getSum(right,type)-getSum(left-1,type);
}

ll query(int node_id,int node_left,int node_right){

	if(node_left >= N || node_left > node_right)return 0;
	if(node_left == node_right)return 0;

	ll ret = 0;
	ret += query(2*node_id+1,node_left,(node_left+node_right)/2);
	ret += query(2*node_id+2,(node_left+node_right)/2+1,min(node_right,N-1));

	vector<Info> L,R;

	for(int i = node_left; i <= (node_left+node_right)/2; i++){

		L.push_back(info[i]);
	}

	for(int i = (node_left+node_right)/2+1; i <= node_right; i++){

		R.push_back(info[i]);
	}

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

		add(L[i].weight,1,COUNT,NUM-1);
		add(L[i].weight,L[i].weight,WEIGHT,NUM-1);
	}

	int L_index = 0,R_index = 0;

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

		if((R_index == R.size()) || (L_index < L.size() && L[L_index].index < R[R_index].index)){

			add(L[L_index].weight,-1,COUNT,NUM-1);
			add(L[L_index].weight,-L[L_index].weight,WEIGHT,NUM-1);
			info[node_left+i].index = L[L_index].index;
			info[node_left+i].weight = L[L_index].weight;
			L_index++;

		}else{

			if(L_index < L.size()){

				ret += calc(R[R_index].weight,NUM-1,COUNT)*C*R[R_index].weight+calc(R[R_index].weight,NUM-1,WEIGHT);
				ret += calc(1,R[R_index].weight-1,WEIGHT)*C+calc(1,R[R_index].weight-1,COUNT)*R[R_index].weight;
			}

			info[node_left+i].index = R[R_index].index;
			info[node_left+i].weight = R[R_index].weight;
			R_index++;
		}
	}

	return ret;
}

int main(){

	scanf("%d %lld",&N,&C);

	for(int i = 0; i < N; i++){

		scanf("%d %lld",&info[i].index,&info[i].weight);
		info[i].index--;
	}

	for(int i = 0; i <= NUM-1; i++){
		BIT[i][COUNT] = 0;
		BIT[i][WEIGHT] = 0;
	}

	printf("%lld\n",query(0,0,N-1));

	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 8352
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define repn(i,n) for(int i=1;i<=n;i++)
#define pb push_back
typedef long long ll;
typedef pair<ll,ll>P;
#define fi first
#define sc second
#define mp make_pair
int n,c;
vector<int>za[(1<<18)];
vector<ll>sum[(1<<18)];
vector<ll>num[(1<<18)];
int a[100005],cc[100005];
void add(int i,int v){
	i += (1<<17)-1;
	za[i].pb(v);
}
void make(){
	for(int i=(1<<18)-1;i>=(1<<17)-1;i--){
		sort(za[i].begin(),za[i].end());
		za[i].erase(unique(za[i].begin(),za[i].end()),za[i].end());
		sum[i].resize(za[i].size()+1,0);
		num[i].resize(za[i].size()+1,0);
	}
	for(int i=(1<<17)-2;i>=0;i--){
		za[i].resize(za[i*2+1].size()+za[i*2+2].size());
		merge(za[i*2+1].begin(),za[i*2+1].end(),za[i*2+2].begin(),za[i*2+2].end(),za[i].begin());
		za[i].erase(unique(za[i].begin(),za[i].end()),za[i].end());
		sum[i].resize(za[i].size()+1,0);
		num[i].resize(za[i].size()+1,0);
	}
}
int f(int x){ return x&-x;}
void addsum(int pos,int k,int a){
	for(int i=k;i<sum[pos].size();i+=f(i)) sum[pos][i]+=a;
}
void addnum(int pos,int k,int a){
	for(int i=k;i<num[pos].size();i+=f(i)) num[pos][i]+=a;
}
ll sumsum(int pos,int k){
	ll res = 0;
	for(int i=k;i>0;i-=f(i)) res+=sum[pos][i];
	return res;
}
ll sumnum(int pos,int k){
	ll res = 0;
	for(int i=k;i>0;i-=f(i)) res+=num[pos][i];
	return res;
}
ll query(int a,int b,int k,int l,int r,int aa){
	if(r<a||b<l) return 0;
	if(a<=l&&r<=b){
		int x = lower_bound(za[k].begin(),za[k].end(),aa)-za[k].begin();
		ll v = sumsum(k,x)*1LL*c + sumnum(k,x)*1LL*aa; //cout<<sumsum(k,x)<<" " << sumnum(k,x)<<endl;
		v += (sumsum(k,sum[k].size()-1)-sumsum(k,x)) + (sumnum(k,sum[k].size()-1)-sumnum(k,x))*1LL*c*aa;
		/*if(v){
				cout<<(sumnum(k,sum[k].size()-1)-sumnum(k,x))<<endl;
				cout<<(sumsum(k,sum[k].size()-1)-sumsum(k,x))<<endl;
				cout<<a<<b<<endl;
				cout<<"===="<<endl;
		}*/
		return v;
	}
	return query(a,b,k*2+1,l,(l+r)/2,aa)+query(a,b,k*2+2,(l+r)/2+1,r,aa);
}
void make2(int a,int b){
	a += (1<<17)-1;
	int c = lower_bound(za[a].begin(),za[a].end(),b)-za[a].begin()+1;
	addsum(a,c,b); addnum(a,c,1);
	while(a){
		a = (a-1)/2;
		c = lower_bound(za[a].begin(),za[a].end(),b)-za[a].begin()+1;
		addsum(a,c,b); addnum(a,c,1);
	}
}
int main(){
	cin>>n>>c;
	rep(i,n)cin>>a[i]>>cc[i];
	rep(i,n){
		add(a[i],cc[i]);
	}
	make(); ll ret = 0; //return 0;
	for(int i=0;i<n;i++){
		ret += query(a[i]+1,(1<<17)-1,0,0,(1<<17)-1,cc[i]);
		//cout<<ret<<endl;
		make2(a[i],cc[i]);
	}
	cout<<ret<<endl;
}
accuracy: 1
time_ms: 550
memory_kb: 72008
final_rank: 8

code_snippet: #include<bits/stdc++.h>
 
using namespace std;
 
typedef long long int64;
 
struct BinaryIndexedTree
{
  vector< int64 > data;
 
  BinaryIndexedTree(int sz) : data(++sz, 0) {}
 
 
  int64 sum(int k)
  {
    int64 ret = 0;
    for(++k; k > 0; k -= k & -k) {
      ret += data[k];
    }
    return (ret);
  }
 
  void add(int k, int64 x)
  {
    for(++k; k < data.size(); k += k & -k) {
      data[k] += x;
    }
  }
};
 
 
struct SegmentTree
{
  int sz;
  vector< BinaryIndexedTree > seg;
  vector< vector< int > > beet;
 
  SegmentTree(int n)
  {
    sz = 1;
    while(sz < n) sz <<= 1;
    beet.resize(2 * sz - 1);
  }
 
  void update(int x, int y, int64 z)
  {
    x += sz - 1;
    seg[x].add(lower_bound(begin(beet[x]), end(beet[x]), y) - begin(beet[x]), z);
    while(x > 0) {
      x = (x - 1) >> 1;
      seg[x].add(lower_bound(begin(beet[x]), end(beet[x]), y) - begin(beet[x]), z);
    }
  }
 
  void preupdate(int x, int y, int64 z)
  {
    x += sz - 1;
    beet[x].push_back(y);
    while(x > 0) {
      x = (x - 1) >> 1;
      beet[x].push_back(y);
    }
  }
 
  void build()
  {
    for(int k = beet.size() - 1; k >= 0; k--) {
      sort(begin(beet[k]), end(beet[k]));
      beet[k].erase(unique(begin(beet[k]), end(beet[k])), end(beet[k]));
    }
    for(int k = 0; k < beet.size(); k++) {
      seg.emplace_back(BinaryIndexedTree(beet[k].size()));
    }
  }
 
  void prequery(int a, int b, int x, int y, int k, int l, int r)
  {
    if(a >= r || b <= l) return;
    if(a <= l && r <= b) {
      beet[k].push_back(y);
      beet[k].push_back(x);
 
      return;
    }
    prequery(a, b, x, y, 2 * k + 1, l, (l + r) >> 1);
    prequery(a, b, x, y, 2 * k + 2, (l + r) >> 1, r);
  }
 
  int64 query(int a, int b, int x, int y, int k, int l, int r)
  {
    if(a >= r || b <= l) return (0);
    if(a <= l && r <= b) {
      int p = y, q = x;
      y = lower_bound(begin(beet[k]), end(beet[k]), y) - begin(beet[k]);
      x = lower_bound(begin(beet[k]), end(beet[k]), x) - begin(beet[k]);
      return (seg[k].sum(y) - seg[k].sum(x));
    }
    return (query(a, b, x, y, 2 * k + 1, l, (l + r) >> 1) + query(a, b, x, y, 2 * k + 2, (l + r) >> 1, r));
  }
 
  int64 query(int a, int b, int x, int y)
  {
    return (query(a, b, x, y, 0, 0, sz));
  }
 
  void prequery(int a, int b, int x, int y)
  {
    prequery(a, b, x, y, 0, 0, sz);
 
  }
};
 
 
int main()
{
  int N, C, X[100000], Y[100000];
 
  cin >> N >> C;
  for(int i = 0; i < N; i++) {
    cin >> X[i] >> Y[i];
    --X[i];
  }
  int64 ret = 0LL;
  SegmentTree bit1(100001), bit2(100001);
 
  for(int i = 0; i < N; i++) {
    bit1.prequery(X[i] + 1, 100001, Y[i], 100000);
    bit2.prequery(X[i] + 1, 100001, Y[i], 100000);
    bit2.prequery(X[i] + 1, 100001, 0, Y[i]);
    bit1.prequery(X[i] + 1, 100001, 0, Y[i]);
    bit1.preupdate(X[i], Y[i], 1);
    bit2.preupdate(X[i], Y[i], Y[i]);
  }
  bit1.build();
  bit2.build();
 
  for(int i = 0; i < N; i++) {
    ret += bit1.query(X[i] + 1, 100001, Y[i], 100000) * Y[i] * C;
    ret += bit2.query(X[i] + 1, 100001, Y[i], 100000);
    ret += bit2.query(X[i] + 1, 100001, 0, Y[i]) * C;
    ret += bit1.query(X[i] + 1, 100001, 0, Y[i]) * Y[i];
    bit1.update(X[i], Y[i], 1);
    bit2.update(X[i], Y[i], Y[i]);
  }
  cout << ret << endl;
}
accuracy: 1
time_ms: 2320
memory_kb: 164056
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int n,c;

struct BITree{
	ll bit[100005];
	BITree(){}
	void update(int k,ll a){
		while(k<=100000){
			bit[k]+=a;
			k+=(k&(-k));
		}
	}

	ll sum(int k){
		ll s=0;
		while(k>0){
			s+=bit[k];
			k-=(k&(-k));
		}
		return s;
	}

	ll query(int a,int b){
		return sum(b)-sum(a);
	}
};

BITree seg,seg2;

int b[100005],w[100005];
P vec_l[100005],vec_r[100005];
P vec[100005];

ll solve(int l,int r){
	int n=r-l;
	if(n<=1)return 0;
	ll ans=0;
	ans+=solve(l,(l+r)/2);
	ans+=solve((l+r)/2,r);
	int li=0,ri=0;
	int size_vl=(l+r)/2-l;
	int size_vr=r-(l+r)/2;
	for(int i=0;i<size_vl;i++){
		vec_l[i]=vec[l+i];
	}
	for(int i=0;i<size_vr;i++){
		vec_r[i]=vec[(l+r)/2+i];
	}
	for(int i=0;i<size_vl;i++){
		seg.update(vec_l[i].second,1);
		seg2.update(vec_l[i].second,vec_l[i].second);
	}
	for(int i=0;i<n;i++){
		if(li<size_vl && (ri==size_vr || vec_l[li].first<vec_r[ri].first)){
			seg.update(vec_l[li].second,-1);
			seg2.update(vec_l[li].second,-vec_l[li].second);
			vec[l+i]=vec_l[li++];
		}else{
			if(ri<size_vr){
				ans+=(ll)seg2.query(0,vec_r[ri].second)*c+seg.query(0,vec_r[ri].second)*vec_r[ri].second;
				ans+=(ll)seg2.query(vec_r[ri].second,100000)+seg.query(vec_r[ri].second,100000)*vec_r[ri].second*c;
			}
			vec[l+i]=vec_r[ri++];
		}
	}
	return ans; 
}

int main(void){
	scanf("%d%d",&n,&c);
	for(int i=0;i<n;i++){
		scanf("%d%d",&b[i],&w[i]);
		b[i]--;
		vec[i]=P(b[i],w[i]);
	}
	printf("%lld\n",solve(0,n));
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 7864
final_rank: 2