rt,一个没过,每次输出的错误信息也不一样
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e4 + 5;
const int inf = 1 << 29;
const int mod = 1e9 + 7;
int n, m;
int ans;
int a[N], v[N];
struct Treap {
int l, r, siz, dat, val, page;
ll sum;
} tr[N << 5];
struct Node {
ll sz, vsum;
};
Node operator + (const Node &lhs, const Node &rhs) {
return (Node){lhs.sz + rhs.sz, lhs.vsum + rhs.vsum};
}
Node operator - (const Node &lhs, const Node &rhs) {
return (Node){lhs.sz - rhs.sz, lhs.vsum - rhs.vsum};
}
int idx;
struct FHQ {
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
tr[x].sum = tr[tr[x].l].sum + tr[tr[x].r].sum + tr[x].page;
}
int get_new(int val, int page) {
tr[++ idx] = {0, 0, 1, rand(), val, page};
return idx;
}
void split(int u, int val, int &x, int &y) {
if (!u) x = y = 0;
else {
if (tr[u].val <= val) x = u, split(tr[u].r, val, tr[x].r, y);
else y = u, split(tr[u].l, val, x, tr[y].l);
pushup(u);
}
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].dat < tr[y].dat) {
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
void insert(int &rt, int val, int page) {
int x, y;
split(rt, val - 1, x, y);
rt = merge(merge(x, get_new(val, page)), y);
}
void remove(int &rt, int val) {
int x, y, z;
split(rt, val, x, y), split(x, val - 1, x, z);
z = merge(tr[z].l, tr[z].r);
rt = merge(merge(x, z), y);
}
Node calc1(int &rt, int val) {
int x, y;
split(rt, val - 1, x, y);
Node res = {tr[x].siz, tr[x].sum};
rt = merge(x, y);
return res;
}
Node calc2(int &rt, int val) {
int x, y;
split(rt, val, x, y);
Node res = {tr[y].siz, tr[y].sum};
rt = merge(x, y);
return res;
}
};
FHQ c[N];
int rt[N];
void ins(int x, int val, int page) {
for (; x <= n; x += x & -x) c[x].insert(rt[x], val, page);
}
void del(int x, int val) {
for (; x <= n; x += x & -x) c[x].remove(rt[x], val);
}
Node query1(int x, int val) {
Node res = (Node){0, 0};
for (; x; x -= x & -x) res = res + c[x].calc1(rt[x], val) - (Node){1, 0};
return res;
}
Node query1(int l, int r, int val) {
if (l > r) return (Node){0, 0};
return query1(r, val) - query1(l - 1, val);
}
Node query2(int x, int val) {
Node res = (Node){0, 0};
for (; x; x -= x & -x) res = res + c[x].calc2(rt[x], val) - (Node){1, 0};
return res;
}
Node query2(int l, int r, int val) {
if (l > r) return (Node){0, 0};
return query2(r, val) - query2(l - 1, val);
}
void add(ll &x, ll y) {
x += y;
if (x >= mod) x -= mod;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
srand(time(0));
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
c[i].insert(rt[i], inf, 0), c[i].insert(rt[i], -inf, 0);
}
ll ans = 0;
for (int i = 1; i <= n; i ++) {
cin >> a[i] >> v[i];
ins(i, a[i], v[i]);
Node t = query2(i - 1, a[i]);
add(ans, t.vsum), add(ans, t.sz * v[i] % mod);
}
for (int i = 0; i < m; i ++) {
int l, r;
cin >> l >> r;
if (l > r) swap(l, r);
if (l != r) {
Node t;
t = query1(l + 1, r - 1, a[l]);
add(ans, mod - t.vsum), add(ans, mod - t.sz * v[l] % mod);
t = query2(l + 1, r - 1, a[l]);
add(ans, t.vsum), add(ans, t.sz * v[l] % mod);
t = query1(l + 1, r - 1, a[r]);
add(ans, t.vsum), add(ans, t.sz * v[r] % mod);
t = query2(l + 1, r - 1, a[r]);
add(ans, mod - t.vsum), add(ans, mod - t.sz * v[r] % mod);
if (a[r] > a[l]) add(ans, v[l] + v[r]);
else add(ans, mod - v[l] - v[r]);
del(l, a[l]), del(r, a[r]);
swap(a[l], a[r]), swap(v[l], v[r]);
ins(l, a[l], v[l]), ins(r, a[r], v[r]);
}
cout << ans << "\n";
}
return 0;
}