HDU5196--DZY Loves Inversions 树状数组 逆序数
题意查询给定[L, R]区间内 逆序对数 ==k的子区间的个数。
我们只需要求出 子区间小于等于k的个数和小于等于k-1的个数,然后相减就得出答案了。
对于i(1≤i≤n),我们计算ri表示[i,ri]的逆序对数小于等于K,且ri的值最大。(ri对应代码中的cnt数组)
显然ri单调不降,我们可以通过用两个指针扫一遍,利用树状数组计算出r数组。
对于每个询问L,R,我们要计算的是∑i=LR[min(R,ri)−i+1]
由于ri具有单调性,那我们直接在上面二分即可,然后记一个前缀和(s数组)。
1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 typedef unsigned long long ull; 16 typedef long long ll; 17 const int inf = 0x3f3f3f3f; 18 const double eps = 1e-8; 19 const int maxn = 1e5+100; 20 int n, q, tot, a[maxn]; 21 ll k, vec[maxn]; 22 int lowbit (int x) 23 { 24 return x & -x; 25 } 26 ll arr[maxn]; 27 int M ; 28 void modify(int x, int d) 29 { 30 while (x < M) 31 { 32 arr[x] += d; 33 x += lowbit(x); 34 } 35 } 36 ll sum(int x) 37 { 38 ll res = 0; 39 while (x) 40 { 41 res += arr[x]; 42 x -= lowbit(x); 43 } 44 return res; 45 } 46 ll cnt[2][maxn]; 47 ll s[2][maxn]; 48 ll solve (int L, int R, ll x, int w) // 小于等于x的数量 49 { 50 if (x < 0) 51 return 0; 52 //int tmp = 0; 53 int tmp = lower_bound(cnt[w]+L, cnt[w]+R+1, (ll)R) - cnt[w]; 54 while (tmp >= R+1) // cnt数组中所有数都小于 R时,,得到的tmp是大于R+1的 55 tmp--; 56 while (cnt[w][tmp] > R && tmp >= L) 57 tmp--; 58 if (tmp < L) 59 return (ll)R*(ll)(R-L+1) - (ll)(L+R)*(ll)(R-L+1)/2; 60 return s[w][tmp] - s[w][L-1] - (ll)(R-tmp)*(ll)(R+tmp+1)/2+ (ll)(R-tmp)*(ll)R; 61 } 62 int main() 63 { 64 #ifndef ONLINE_JUDGE 65 freopen("in.txt","r",stdin); 66 freopen("out.txt", "w", stdout); 67 #endif 68 while (~scanf ("%d%d%I64d", &n, &q, &k)) 69 { 70 M = n + 10; 71 memset(arr, 0, sizeof (arr)); 72 memset(cnt, 0, sizeof (cnt)); 73 memset(s, 0, sizeof(s)); 74 for (int i = 0; i < n; i++) 75 { 76 scanf ("%I64d", vec+i); 77 a[i] = vec[i]; 78 } 79 sort (vec, vec+n); 80 tot = unique(vec, vec+n) - vec; 81 for (int i = 0; i < n; i++) 82 { 83 a[i] = lower_bound(vec, vec+tot, a[i]) - vec + 2; //离散化 84 } 85 ll res = 0; 86 //小于等于k 87 for (int i = 0, j = 0; i < n; i++) 88 { 89 for ( ; j < n && res <= k; j++) 90 { 91 res += (j - i) - sum(a[j]); 92 modify(a[j], 1); 93 } 94 if (res >= k) 95 cnt[1][i] = (res > k ? max(0,j -1-1): j-1) ; // -1是因为 j先加了一下, 才跳出 循环的 96 else 97 cnt[1][i] = j-1-1; 98 s[1][i] = s[1][i-1] + cnt[1][i] - (i); 99 modify(a[i], -1); 100 res -= sum(a[i]-1); 101 } 102 103 //小于等于k-1 104 res = 0; 105 for (int i = 0, j = 0; i < n; i++) 106 { 107 for ( ; j < n && res <= (k-1); j++) 108 { 109 res += (j-i) - sum(a[j]); 110 modify(a[j], 1); 111 } 112 if (res >= k-1) 113 cnt[0][i] = (res > (k-1) ? max(j-1-1,0) : j-1); 114 else 115 cnt[0][i] = j-1-1; 116 117 s[0][i] = s[0][i-1] + cnt[0][i] - (i); 118 modify(a[i], -1); 119 res -= sum(a[i]-1); 120 } 121 for (int i = 0; i < q; i++) 122 { 123 int u, v; 124 scanf ("%d%d", &u, &v); 125 u--, v--; 126 if (u > v) 127 swap(u, v); 128 ll ans1 = solve(u, v, k, 1); 129 ll ans2 = solve(u, v, k-1, 0); 130 if (k == 0) 131 ans1 += (v-u+1); // 考虑形如[a, a]的区间 132 printf("%I64d\n", ans1-ans2 ); 133 } 134 } 135 return 0; 136 }
转载于:https://www.cnblogs.com/oneshot/p/4384639.html
HDU5196--DZY Loves Inversions 树状数组 逆序数相关推荐
- CodeForces - 987E Petr and Permutations(树状数组+逆序对定理)
题目链接:点击查看 题目大意:给出一个长度为 n 的序列,可能打乱过 3 * n 次,也可能打乱过 7 * n + 1 次,问到底打乱过多少次 题目分析:首先看出,3 * n 和 7 * n + 1 ...
- 牛客 - tokitsukaze and Inverse Number(树状数组+逆序对定理)
题目链接:点击查看 题目大意:给出一个长度为 n 的排列 a,需要执行 q 次操作,每次操作会将区间 [ l , r ] 内的数循环右移 k 次,现在需要回答每次操作后排列的逆序对数,只需要回答奇偶即 ...
- Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 1539 Solved: 665 [Submit][Status][ ...
- ZOJ - 4117 BaoBao Loves Reading(树状数组求区间内不同数的个数+思维)
题目链接:点击查看 题目大意:给出一个长度为 n 的序列,其意义为第 i 秒需要看第 a[ i ] 种书,书架上可以供应无限种书,但是书桌有容量,当书桌上的容量达到上限后,如果还想从书架上拿新书来看, ...
- dp 树状数组 逆序元组
wmq的队伍 发布时间: 2017年4月9日 17:06 最后更新: 2017年4月9日 17:07 时间限制: 2000ms 内存限制: 512M 描述 交大上课需要打卡,于是在上课前的 ...
- cf1042d 树状数组逆序对+离散化
/* 给定一个数组,要求和小于t的段落总数 求前缀和 dp[i]表示以第i个数为结尾的小于t的段落总数,sum[i]-sum[l]<t; sum[i]-t<sum[l],所以只要找到满足条 ...
- sort it 树状数组+逆序对
sum[i]是1-i所有1的和,而i-sum[a[i]]就是在a[i]后面的数,即在i之前出现,却比他大的数.1是加在a[i]上,即i实际应该放的位置.而c[i]是为sum做准备的 1 #includ ...
- 蓝桥杯2014届试题9题 小朋友排队(树状数组+类逆序对)
题目: 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 n 个小朋友站成一排.现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友. 每个小朋友都有一个不高兴的 ...
- szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】
树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...
最新文章
- Mule,目前综合状态最良好的开源ESB方案
- 2021年高考英语卷三成绩查询,2021年全国3卷高考外语卷难不难,今年全国3卷高考外语卷难度系数点评...
- 备战520|Python花式表白的几种姿势
- Spider局域网通讯软件
- Python中使用xpath结合contains
- http 性能测试. Apache ab 使用.
- 2015 ACM/ICPC Asia Regional Changchun Online HDU - 5441 (离线+并查集)
- 深度deepin安装腾达U12无线网卡驱动
- 用OOP设计以下场景。太阳发出太阳光,照射在墙壁上,在地面形成影子。
- 用计算机弹极乐净土谱,极乐净土计算器乐谱
- html单元格点击变色,当我将鼠标悬停在html表格上时,更改单元格的颜色
- 千古第一文人苏轼的众CP
- AT24Cxx读写全面理解
- 自动驾驶之-MATLAB环境下利用单目摄像头和语义分割创建占位栅格(occupancy grid)
- 在线预览doc,docx文档
- nodejs安装及环境配置
- 关于relief算法选择特征的问题
- bio 生信博主网站 blog
- Pycharm远程访问ssh,远程访问服务器(xshell访问服务器)
- ORACLE 行迁移 chained_rows分析
热门文章
- openwrt系统安装到云服务器异常,OpenWrt路由器系统下服务OpenClash 安装教程及其折腾踩坑记录...
- DATA URI schema(data:base64)协议常用数据格式
- Mysql 会导致锁表的语法
- python离线安装国内镜像OpenCV
- 那些侵占我碎片时间的“强盗”
- C#自定义控件,在项目工具箱中加入自定义控件,调用自定义控件
- 从Ecipse中导出程序至apk
- 从HBase中移除WAL?3D XPoint技术带来的变革
- Hystrix 资料简单梳理
- ES6 generator