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数组)。
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 1e5+;
int n, q, tot, a[maxn];
ll k, vec[maxn];
int lowbit (int x)
{
return x & -x;
}
ll arr[maxn];
int M ;
void modify(int x, int d)
{
while (x < M)
{
arr[x] += d;
x += lowbit(x);
}
}
ll sum(int x)
{
ll res = ;
while (x)
{
res += arr[x];
x -= lowbit(x);
}
return res;
}
ll cnt[][maxn];
ll s[][maxn];
ll solve (int L, int R, ll x, int w) // 小于等于x的数量
{
if (x < )
return ;
//int tmp = 0;
int tmp = lower_bound(cnt[w]+L, cnt[w]+R+, (ll)R) - cnt[w];
while (tmp >= R+) // cnt数组中所有数都小于 R时,,得到的tmp是大于R+1的
tmp--;
while (cnt[w][tmp] > R && tmp >= L)
tmp--;
if (tmp < L)
return (ll)R*(ll)(R-L+) - (ll)(L+R)*(ll)(R-L+)/;
return s[w][tmp] - s[w][L-] - (ll)(R-tmp)*(ll)(R+tmp+)/+ (ll)(R-tmp)*(ll)R;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt", "w", stdout);
#endif
while (~scanf ("%d%d%I64d", &n, &q, &k))
{
M = n + ;
memset(arr, , sizeof (arr));
memset(cnt, , sizeof (cnt));
memset(s, , sizeof(s));
for (int i = ; i < n; i++)
{
scanf ("%I64d", vec+i);
a[i] = vec[i];
}
sort (vec, vec+n);
tot = unique(vec, vec+n) - vec;
for (int i = ; i < n; i++)
{
a[i] = lower_bound(vec, vec+tot, a[i]) - vec + ; //离散化
}
ll res = ;
//小于等于k
for (int i = , j = ; i < n; i++)
{
for ( ; j < n && res <= k; j++)
{
res += (j - i) - sum(a[j]);
modify(a[j], );
}
if (res >= k)
cnt[][i] = (res > k ? max(,j --): j-) ; // -1是因为 j先加了一下, 才跳出 循环的
else
cnt[][i] = j--;
s[][i] = s[][i-] + cnt[][i] - (i);
modify(a[i], -);
res -= sum(a[i]-);
} //小于等于k-1
res = ;
for (int i = , j = ; i < n; i++)
{
for ( ; j < n && res <= (k-); j++)
{
res += (j-i) - sum(a[j]);
modify(a[j], );
}
if (res >= k-)
cnt[][i] = (res > (k-) ? max(j--,) : j-);
else
cnt[][i] = j--; s[][i] = s[][i-] + cnt[][i] - (i);
modify(a[i], -);
res -= sum(a[i]-);
}
for (int i = ; i < q; i++)
{
int u, v;
scanf ("%d%d", &u, &v);
u--, v--;
if (u > v)
swap(u, v);
ll ans1 = solve(u, v, k, );
ll ans2 = solve(u, v, k-, );
if (k == )
ans1 += (v-u+); // 考虑形如[a, a]的区间
printf("%I64d\n", ans1-ans2 );
}
}
return ;
}
HDU5196--DZY Loves Inversions 树状数组 逆序数的更多相关文章
- HDU 4911 (树状数组+逆序数)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4911 题目大意:最多可以交换K次,就最小逆序对数 解题思路: 逆序数定理,当逆序对数大于0时,若ak ...
- hdu2838Cow Sorting(树状数组+逆序数)
题目链接:点击打开链接 题意描写叙述:给定一个长度为100000的数组,每一个元素范围在1~100000,且互不同样,交换当中的随意两个数须要花费的代价为两个数之和. 问怎样交换使数组有序.花费的代价 ...
- HDU3465 树状数组逆序数
Life is a Line Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)T ...
- [树状数组+逆序对][NOIP2013]火柴排队
火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...
- hdu 5497 Inversion 树状数组 逆序对,单点修改
Inversion Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5497 ...
- Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对
题目:http://codevs.cn/problem/3286/ 3286 火柴排队 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : ...
- Bzoj 2789: [Poi2012]Letters 树状数组,逆序对
2789: [Poi2012]Letters Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 278 Solved: 185[Submit][Stat ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1539 Solved: 665[Submit][Status][Di ...
随机推荐
- C++获得系统路径
源码: [cpp] view plaincopy #include <Shlobj.h> #include <stdio.h> #include <locale.h> ...
- [转] gdb的基本工作原理
转自: http://www.spongeliu.com/linux/howgdbwork/ 还是面某M的时候,面试官问我:“用过gdb么?” 答:“用过,调了两年bug了”.“那好,给我解释下gdb ...
- 【移动开发】Android中将我们平时积累的工具类打包
Android开发的组件打包成JAR安装包,通过封闭成JAR包,可以重复利用,非常有利于扩展和减少工作重复性.这里为了讲解方便,我用了之前的一个代码框架中核心部分,不了解的可以回头看一下:http:/ ...
- 批量升级BMC固件asu64、ipmitool
需求:通过服务器远程管理IP批量升级IMM.UEFI固件 工具:asu64.ipmitool.iflash64.cdc_interface.sh 下载:http://pan.baidu.com/s/1 ...
- SpringMVC07处理器方法的返回值
<body> <!--返回值是string的内部视图 --> <a href="user/add">add</a> <!--返 ...
- (转)C#读取文件路径
//获取包含清单的已加载文件的路径或 UNC 位置. public static string sApplicationPath = Assembly.GetExecutingAssembly ( ) ...
- (转)JQuery中$.ajax()方法参数详解
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- TextView drawablePadding没有效果
1.当TextView 设置宽度设置为match_parent的时候 TextView drawablePadding没有效果 ,字设置了center位置,但是和左边的图片离开很远 2.当TextVi ...
- java学习笔记(13) —— google GSON 实现json转化方法
1.配置struts.xml <action name="getGsonAction" class="com.test.action.json.GetGsonAct ...
- 淘宝接口实现ip归属地查询
<?php header('content-type:text/html;charset=utf-8'); /*获取当前ip归属地 调用淘宝接口 */ function get_ip_place ...