这个题目没什么思维量,还比较简单,就是离散化要加上每一个值的后面一个值,然后每一个值放进去的不是1 ,而是这个值与下一个点的差值。
因为这个数代表了一堆数,然后每一次的找到了的逆序对都要乘以这个num。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <string> #include <iostream> #include <map> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; const int maxn = 4e5 + 10; typedef long long ll; int num[maxn], a[maxn], b[maxn]; pair<ll, ll>ex[maxn]; struct node { int l, r; int num; }tree[4 * maxn]; void build(int id, int l, int r) { tree[id].l = l; tree[id].r = r; if (l == r) { tree[id].num = 0; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); } int query(int id, int x, int y) { int l = tree[id].l; int r = tree[id].r; if (x <= l && y >= r) { return tree[id].num; } int ans = 0; int mid = (l + r) >> 1; if (x <= mid) ans += query(id << 1, x, y); if (y > mid) ans += query(id << 1 | 1, x, y); return ans; } void push_up(int id) { tree[id].num =tree[id << 1].num+tree[id << 1 | 1].num; } void update(int id, int x, int val) { int l = tree[id].l; int r = tree[id].r; if (l == r) { //printf("id=%d x=%d val=%d\n", id, x, val); tree[id].num = val; return; } int mid = (l + r) >> 1; if (x <= mid) update(id << 1, x, val); else update(id << 1 | 1, x, val); push_up(id); } int main() { int n, tot = 0; scanf("%d", &n); for (int i = 1; i <= n; i++) { int u, v; scanf("%d%d", &u, &v); ex[i] = make_pair(u, v); a[tot++] = u, a[tot++] = v; a[tot++] = u + 1, a[tot++] = v + 1; } sort(a, a + tot); int len = unique(a, a + tot) - a; //printf("len=%d\n", len); num[len - 1] = 1; for (int i = 0; i < len - 1; i++) { num[i] = a[i + 1] - a[i]; //printf("num[%d]=%d a[%d]=%d\n", i, num[i], i, a[i]); } memcpy(b, a, sizeof(a)); for(int i=1;i<=n;i++) { ex[i].first = lower_bound(a, a + len, ex[i].first) - a; ex[i].second = lower_bound(a, a + len, ex[i].second) - a; //printf("ex[%d] %lld %lld\n", i, ex[i].first, ex[i].second); } for (int i = 1; i <= n; i++) swap(a[ex[i].first], a[ex[i].second]), swap(num[ex[i].first], num[ex[i].second]); ll ans = 0; build(1, 1, len); for(int i=0;i<len;i++) { int l = lower_bound(b, b + len, a[i]) - b + 1; //printf("l=%d\n", l); ans += query(1, l, len) * 1ll * num[i]; update(1, l, num[i]); //printf("ans=%lld\n", ans); } printf("%lld\n", ans); return 0; }
题目二:E. Physical Education Lessons
这个空间开的特别变态,空间要开的很大,而且这个空间给的也不是很多,没什么思维量,比较简单。
开始在第17发 re到我怀疑我写搓了,然后就是第一发mle。。。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <string> #include <iostream> #include <map> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; const int maxn1 = 1e7 + 5e6 + 10; const int maxn = 3e5 + 10; typedef long long ll; int a[maxn * 4], num[maxn1]; struct edge { int u, v, opt; edge(int u = 0, int v = 0, int opt = 0) :u(u), v(v), opt(opt) {} }order[maxn * 2]; struct node { int lazy; int sum, num; }tree[maxn1]; void push_up(int id) { tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum; tree[id].num = tree[id << 1].num + tree[id << 1 | 1].num; } void build(int id, int l, int r) { tree[id].lazy = -1; if (l == r) { tree[id].sum = num[l]; tree[id].num = num[l]; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); push_up(id); } void push_down(int id) { if (tree[id].lazy != -1) { tree[id << 1].sum = tree[id << 1].num*tree[id].lazy; tree[id << 1 | 1].sum = tree[id << 1 | 1].num*tree[id].lazy; tree[id << 1].lazy = tree[id].lazy; tree[id << 1 | 1].lazy = tree[id].lazy; tree[id].lazy = -1; } } void update(int id,int l,int r, int x, int y, int k) { push_down(id); if (x <= l && y >= r) { tree[id].lazy = k; tree[id].sum = tree[id].num*k; return; } int mid = (l + r) >> 1; if (x <= mid) update(id << 1, l, mid, x, y, k); if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, k); push_up(id); } int main() { int n, m, tot = 1; scanf("%d%d", &n, &m); a[0] = 1; for (int i = 1; i <= m; i++) { int u, v, k; scanf("%d%d%d", &u, &v, &k); order[i] = edge(u, v, k); a[tot++] = u, a[tot++] = u + 1; a[tot++] = v, a[tot++] = v + 1; } sort(a, a + tot); int len = unique(a, a + tot) - a; for (int i = 1; i <= m; i++) { order[i].u = lower_bound(a, a + len, order[i].u) - a + 1; order[i].v = lower_bound(a, a + len, order[i].v) - a + 1; } num[len] = n - a[len - 1] + 1; for (int i = 0; i < len - 1; i++) { num[i + 1] = a[i + 1] - a[i]; //printf("num[%d]=%d\n", i + 1, num[i + 1]); } //for (int i = 1; i <= len; i++) printf("i=%d %d\n",i, num[i]); build(1, 1, len); //printf("len=%d\n", len); for (int i = 1; i <= m; i++) { int l = order[i].u; int r = order[i].v; int k = order[i].opt; //printf("l=%d r=%d\n", l, r); if (l > r) swap(l, r); update(1,1,len, l, r, k - 1); ll ans = tree[1].sum; printf("%lld\n", ans); } return 0; }