题意查询给定[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 树状数组 逆序数的更多相关文章

  1. HDU 4911 (树状数组+逆序数)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4911 题目大意:最多可以交换K次,就最小逆序对数 解题思路: 逆序数定理,当逆序对数大于0时,若ak ...

  2. hdu2838Cow Sorting(树状数组+逆序数)

    题目链接:点击打开链接 题意描写叙述:给定一个长度为100000的数组,每一个元素范围在1~100000,且互不同样,交换当中的随意两个数须要花费的代价为两个数之和. 问怎样交换使数组有序.花费的代价 ...

  3. HDU3465 树状数组逆序数

    Life is a Line Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)T ...

  4. [树状数组+逆序对][NOIP2013]火柴排队

    火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...

  5. hdu 5497 Inversion 树状数组 逆序对,单点修改

    Inversion Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5497 ...

  6. Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

    题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组  时间限制: 1 s   空间限制: 128000 KB   题目等级 : ...

  7. Bzoj 2789: [Poi2012]Letters 树状数组,逆序对

    2789: [Poi2012]Letters Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 278  Solved: 185[Submit][Stat ...

  8. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  9. Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1539  Solved: 665[Submit][Status][Di ...

随机推荐

  1. Android入门之ActionBar实现Tab导航

    效果图: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=&qu ...

  2. 1033 - Merging Maps

    Pictures taken from an airplane or satellite of an ar ea to be mapped are often of sufficiently high ...

  3. NYOJ-745蚂蚁的难题(二)

    这道题和求字段和的要求就差一点,就是那个是一条链, 这个是个环,关于这么环,刚开始按照链那种方式推倒状态转移方程,但是没有写出来,后来看题解,才看到原来还是转化为普通的单链来做,好多题都是由不会的转化 ...

  4. div整体布局分析

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 华为S5300交换机配置基于VLAN的本地端口镜像

    配置思路 1.  将Ethernet0/0/20接口配置为观察端口(监控端口) 2.  将VLAN 1.11.12.13.14配置为镜像VLAN 配置步骤 1.  配置观察端口 <Switch& ...

  6. 开发中遇到的java小知识

    今天在优化一个功能的时候遇到了instr与substr函数,之前没有接触过这两个函数,但是今天无意中用到,一查才发现,真是实用的一对兄弟啊. 先来说说substr函数,这个函数返回的是字符串的一部分. ...

  7. angularjs中的绑定策略“@”,“=”,“&”实例

    <!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...

  8. oracle 空置排在最后显示

    nulls last select * from emp order by comm select * from emp order by comm desc select * from emp or ...

  9. Java下载Servlet Demo

    request.setCharacterEncoding("utf-8"); String name=request.getParameter("name"); ...

  10. libusb简介

    概述 libusb是一个C库,它提供了通用的访问USB设备. 它的目的是供开发人员使用方便的生产与USB通信硬件的应用程序. 可移植的: 使用一个跨平台API,它提供了访问USB设备在Linux上,O ...