题目一:E. Infinite Inversions

这个题目没什么思维量,还比较简单,就是离散化要加上每一个值的后面一个值,然后每一个值放进去的不是1 ,而是这个值与下一个点的差值。

因为这个数代表了一堆数,然后每一次的找到了的逆序对都要乘以这个num。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <queue>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <string>
  8. #include <iostream>
  9. #include <map>
  10. #define inf 0x3f3f3f3f
  11. #define inf64 0x3f3f3f3f3f3f3f3f
  12. using namespace std;
  13. const int maxn = 4e5 + ;
  14. typedef long long ll;
  15. int num[maxn], a[maxn], b[maxn];
  16. pair<ll, ll>ex[maxn];
  17. struct node {
  18. int l, r;
  19. int num;
  20. }tree[ * maxn];
  21.  
  22.  
  23. void build(int id, int l, int r) {
  24. tree[id].l = l;
  25. tree[id].r = r;
  26. if (l == r) {
  27. tree[id].num = ;
  28. return;
  29. }
  30. int mid = (l + r) >> ;
  31. build(id << , l, mid);
  32. build(id << | , mid + , r);
  33. }
  34.  
  35. int query(int id, int x, int y) {
  36. int l = tree[id].l;
  37. int r = tree[id].r;
  38. if (x <= l && y >= r) {
  39. return tree[id].num;
  40. }
  41. int ans = ;
  42. int mid = (l + r) >> ;
  43. if (x <= mid) ans += query(id << , x, y);
  44. if (y > mid) ans += query(id << | , x, y);
  45. return ans;
  46. }
  47.  
  48. void push_up(int id) {
  49. tree[id].num =tree[id << ].num+tree[id << | ].num;
  50. }
  51.  
  52. void update(int id, int x, int val) {
  53. int l = tree[id].l;
  54. int r = tree[id].r;
  55. if (l == r) {
  56. //printf("id=%d x=%d val=%d\n", id, x, val);
  57. tree[id].num = val;
  58. return;
  59. }
  60. int mid = (l + r) >> ;
  61. if (x <= mid) update(id << , x, val);
  62. else update(id << | , x, val);
  63. push_up(id);
  64. }
  65.  
  66. int main() {
  67. int n, tot = ;
  68. scanf("%d", &n);
  69. for (int i = ; i <= n; i++) {
  70. int u, v;
  71. scanf("%d%d", &u, &v);
  72. ex[i] = make_pair(u, v);
  73. a[tot++] = u, a[tot++] = v;
  74. a[tot++] = u + , a[tot++] = v + ;
  75. }
  76. sort(a, a + tot);
  77. int len = unique(a, a + tot) - a;
  78. //printf("len=%d\n", len);
  79. num[len - ] = ;
  80. for (int i = ; i < len - ; i++) {
  81. num[i] = a[i + ] - a[i];
  82. //printf("num[%d]=%d a[%d]=%d\n", i, num[i], i, a[i]);
  83. }
  84. memcpy(b, a, sizeof(a));
  85. for(int i=;i<=n;i++)
  86. {
  87. ex[i].first = lower_bound(a, a + len, ex[i].first) - a;
  88. ex[i].second = lower_bound(a, a + len, ex[i].second) - a;
  89. //printf("ex[%d] %lld %lld\n", i, ex[i].first, ex[i].second);
  90. }
  91. for (int i = ; i <= n; i++) swap(a[ex[i].first], a[ex[i].second]), swap(num[ex[i].first], num[ex[i].second]);
  92. ll ans = ;
  93. build(, , len);
  94. for(int i=;i<len;i++)
  95. {
  96. int l = lower_bound(b, b + len, a[i]) - b + ;
  97. //printf("l=%d\n", l);
  98. ans += query(, l, len) * 1ll * num[i];
  99. update(, l, num[i]);
  100. //printf("ans=%lld\n", ans);
  101. }
  102. printf("%lld\n", ans);
  103. return ;
  104. }

离散化+线段树

今天20190809来补一下这个题目的树状数组,一直都没有学过树状数组,今天浅显的学习了一下,学习网站https://www.cnblogs.com/xenny/p/9739600.html

这个讲的还是很详细也很容易理解。

这个还是照着上面的思路,只是把线段树换成树状数组。

今天感觉自己傻了,这个树状数组容易写,但是下面的这个离散化写搓了,这个num数组应该记录的是这个数带这五个数的后面一位有多少个

而不可以是这个数和这个数的前面一位之间有多少个,因为这个比这个数小的肯定比大于这个数的数小,所以肯定是可以构成逆序对的。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <queue>
  5. #include <vector>
  6. #include <string>
  7. #include <algorithm>
  8. #include <iostream>
  9. #include <map>
  10. #define inf 0x3f3f3f3f
  11. #define inf64 0x3f3f3f3f3f3f3f3f
  12. using namespace std;
  13. typedef long long ll;
  14. const int maxn = 4e5 + ;
  15. int n;
  16. ll c[maxn]; //对应原数组和树状数组
  17.  
  18. int lowbit(int x) {
  19. return x & (-x);
  20. }
  21.  
  22. void updata(int i, ll k) { //在i位置加上k
  23. while (i <= n) {
  24. c[i] += k;
  25. i += lowbit(i);
  26. }
  27. }
  28.  
  29. ll getsum(int i) { //求A[1 - i]的和
  30. ll res = ;
  31. while (i > ) {
  32. res += c[i];
  33. i -= lowbit(i);
  34. }
  35. return res;
  36. }
  37.  
  38. ll num[maxn];
  39. ll b[maxn], a[maxn];
  40. struct node {
  41. int l, r;
  42. node(int l = , int r = ) :l(l), r(r) {}
  43. }ex[maxn];
  44.  
  45. int main() {
  46. int m, tot = ;
  47. scanf("%d", &m);
  48. for (int i = ; i <= m; i++) {
  49. int l, r;
  50. scanf("%d%d", &l, &r);
  51. ex[i] = node(l, r);
  52. b[++tot] = l; b[++tot] = l + ;
  53. b[++tot] = r; b[++tot] = r + ;
  54. }
  55. sort(b + , b + + tot);
  56. n = unique(b + , b + + tot) - b - ;
  57. num[n] = ;
  58. for (int i = ; i < n; i++) {
  59. num[i] = b[i + ] - b[i];
  60. }
  61. memcpy(a, b, sizeof(b));
  62. for (int i = ; i <= m; i++) {
  63. ex[i].l = lower_bound(b + , b + + n, ex[i].l) - b;
  64. ex[i].r = lower_bound(b + , b + + n, ex[i].r) - b;
  65. }
  66. for (int i = ; i <= m; i++) {
  67. swap(a[ex[i].l], a[ex[i].r]), swap(num[ex[i].l], num[ex[i].r]);
  68. }
  69. ll ans = ;
  70. for (int i = ; i <= n; i++) {
  71. int l = lower_bound(b + , b + + n, a[i]) - b;
  72. ll res = getsum(n) - getsum(l);
  73. ans += res * num[i];
  74. updata(l, num[i]);
  75. }
  76. printf("%lld\n", ans);
  77. return ;
  78. }

树状数组

题目二:E. Physical Education Lessons

这个空间开的特别变态,空间要开的很大,而且这个空间给的也不是很多,没什么思维量,比较简单。

开始在第17发 re到我怀疑我写搓了,然后就是第一发mle。。。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <queue>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <string>
  8. #include <iostream>
  9. #include <map>
  10. #define inf 0x3f3f3f3f
  11. #define inf64 0x3f3f3f3f3f3f3f3f
  12. using namespace std;
  13. const int maxn1 = 1e7 + 5e6 + ;
  14. const int maxn = 3e5 + ;
  15. typedef long long ll;
  16. int a[maxn * ], num[maxn1];
  17. struct edge {
  18. int u, v, opt;
  19. edge(int u = , int v = , int opt = ) :u(u), v(v), opt(opt) {}
  20. }order[maxn * ];
  21. struct node {
  22. int lazy;
  23. int sum, num;
  24. }tree[maxn1];
  25.  
  26. void push_up(int id) {
  27. tree[id].sum = tree[id << ].sum + tree[id << | ].sum;
  28. tree[id].num = tree[id << ].num + tree[id << | ].num;
  29. }
  30.  
  31. void build(int id, int l, int r) {
  32. tree[id].lazy = -;
  33. if (l == r) {
  34. tree[id].sum = num[l];
  35. tree[id].num = num[l];
  36. return;
  37. }
  38. int mid = (l + r) >> ;
  39. build(id << , l, mid);
  40. build(id << | , mid + , r);
  41. push_up(id);
  42. }
  43.  
  44. void push_down(int id) {
  45. if (tree[id].lazy != -) {
  46. tree[id << ].sum = tree[id << ].num*tree[id].lazy;
  47. tree[id << | ].sum = tree[id << | ].num*tree[id].lazy;
  48. tree[id << ].lazy = tree[id].lazy;
  49. tree[id << | ].lazy = tree[id].lazy;
  50. tree[id].lazy = -;
  51. }
  52. }
  53.  
  54. void update(int id,int l,int r, int x, int y, int k) {
  55. push_down(id);
  56. if (x <= l && y >= r) {
  57. tree[id].lazy = k;
  58. tree[id].sum = tree[id].num*k;
  59. return;
  60. }
  61. int mid = (l + r) >> ;
  62. if (x <= mid) update(id << , l, mid, x, y, k);
  63. if (y > mid) update(id << | , mid + , r, x, y, k);
  64. push_up(id);
  65. }
  66.  
  67. int main() {
  68. int n, m, tot = ;
  69. scanf("%d%d", &n, &m);
  70. a[] = ;
  71. for (int i = ; i <= m; i++) {
  72. int u, v, k;
  73. scanf("%d%d%d", &u, &v, &k);
  74. order[i] = edge(u, v, k);
  75. a[tot++] = u, a[tot++] = u + ;
  76. a[tot++] = v, a[tot++] = v + ;
  77. }
  78. sort(a, a + tot);
  79. int len = unique(a, a + tot) - a;
  80. for (int i = ; i <= m; i++) {
  81. order[i].u = lower_bound(a, a + len, order[i].u) - a + ;
  82. order[i].v = lower_bound(a, a + len, order[i].v) - a + ;
  83. }
  84. num[len] = n - a[len - ] + ;
  85. for (int i = ; i < len - ; i++) {
  86. num[i + ] = a[i + ] - a[i];
  87. //printf("num[%d]=%d\n", i + 1, num[i + 1]);
  88. }
  89. //for (int i = 1; i <= len; i++) printf("i=%d %d\n",i, num[i]);
  90. build(, , len);
  91. //printf("len=%d\n", len);
  92. for (int i = ; i <= m; i++) {
  93. int l = order[i].u;
  94. int r = order[i].v;
  95. int k = order[i].opt;
  96. //printf("l=%d r=%d\n", l, r);
  97. if (l > r) swap(l, r);
  98. update(,,len, l, r, k - );
  99. ll ans = tree[].sum;
  100. printf("%lld\n", ans);
  101. }
  102. return ;
  103. }

离散化+线段树

线段树 离散化 E. Infinite Inversions E. Physical Education Lessons的更多相关文章

  1. E. Physical Education Lessons 动态开辟线段树区间更新

    E. Physical Education Lessons time limit per test 1 second memory limit per test 256 megabytes input ...

  2. POJ 2528 Mayor's posters(线段树+离散化)

    Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...

  3. poj 2528 Mayor's posters(线段树+离散化)

    /* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...

  4. [poj2528] Mayor's posters (线段树+离散化)

    线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...

  5. [UESTC1059]秋实大哥与小朋友(线段树, 离散化)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...

  6. poj 2528 Mayor's posters 线段树+离散化技巧

    poj 2528 Mayor's posters 题目链接: http://poj.org/problem?id=2528 思路: 线段树+离散化技巧(这里的离散化需要注意一下啊,题目数据弱看不出来) ...

  7. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

  8. D - Mayor's posters(线段树+离散化)

    题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...

  9. 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex

    题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...

随机推荐

  1. java的图形化界面 文本区JTextArea的程序例子

    package java1;     //使用时这个改成你的包名即可//文本区 JTextArea import javax.swing.*;import java.awt.*;import java ...

  2. Python-气象-大气科学-可视化绘图系列(三)—— 地图上自动标注省会名称(demo调整中)(代码+示例)

    本文为原创文章 本文链接:https://www.cnblogs.com/zhanling/p/12606990.html # -*- coding: utf-8 -*- ''' Author: He ...

  3. 带你五分钟了解python的函数式编程与闭包

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:梁唐 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行 ...

  4. 10个步骤教你如何安装Anaconda安装,Python数据分析入门必看

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:小白 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行 ...

  5. 2. Git-命令行-删除本地和远程分支

    命令行方式 Git Bash: 切换到要操作的项目文件夹 命令行 : $ cd <ProjectPath> 查看项目的分支们(包括本地和远程) 命令行 : $ git branch -a ...

  6. Jmeter--Plugins Manager安装及常用的插件介绍

    jmeter 客户端 内置的插件管理工具Plugins Manager 1.下载地址:https://jmeter-plugins.org/install/Install/ 2.将下载的文件拷贝的你的 ...

  7. python 进阶篇 函数装饰器和类装饰器

    函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...

  8. python爬虫-User-Agent的伪造

    某些网站会识别python爬虫程序并阻断,通过构造User_Agent可以抵抗某些反爬虫机制 用fake-useragent这个库就能很好的实现 pycharm中安装步骤 产生随机的User-Agen ...

  9. 2019-2020-1 20199328《Linux内核原理与分析》第六周作业

    使用gdb跟踪分析一个系统调用内核函数 首先我们删除本身的menu目录,并从github上克隆一个menu,并进行编译 编译过程 现在找到test.c文件,加入上个实验中做的getPid()方法 利用 ...

  10. Windows API 中 OVERLAPPED 结构体 初始化

    出处:https://github.com/microsoft/Windows-classic-samples/blob/1d363ff4bd17d8e20415b92e2ee989d615cc0d9 ...