计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组

题目链接:https://nanti.jisuanke.com/t/16443

题意:

  给你一个由1~n构成的正整数序列,有m组询问,每组询问要求输出[l , r]区间内的逆序对个数。

数据范围:

  对于100%的数据,满足1 <= n,m <= 30000,l < r,∑ | l[i] - l[i-1] | + ∑ | r[i] - r[i-1] | <= 7 * 10^6。

 

题解:

  如果知道区间[l , r]中的逆序对个数,那么也可以快速求出区间[l-1 , r],[l+1 , r],[l , r-1],[l , r+1]的逆序对个数。

  ① [l-1 , r]的个数 = [l , r]的个数 + [l , r]中比a[l-1]小的元素的个数

  ② [l+1 , r]的个数 = [l , r]的个数 - [l+1 , r]中比a[l]小的元素的个数

  ③ [l , r-1]的个数 = [l , r]的个数 - [l , r-1]中比a[r]大的元素的个数

  ④ [l , r+1]的个数 = [l , r]的个数 + [l , r]中比a[r+1]大的元素的个数

  查询区间内比x大(小)的元素的个数用树状数组实现。

  比x大的元素个数 = query(x - 1)

  比x小的元素个数 = query(n) - query(x)  (区间内元素总个数减去大于等于x的元素个数)

  先假定现在的区间为[1 , 1],逆序对总个数为0。对于每一组询问,只要不断移动当前区间的左右端点,并同时更新答案,直至当前区间与询问区间相同即可,输出sum值。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define MAX_N 30005
 5 
 6 using namespace std;
 7 
 8 int n,m;
 9 int a[MAX_N];
10 int dat[MAX_N];
11 
12 void update(int k,int a)
13 {
14     while(k<=n)
15     {
16         dat[k]+=a;
17         k+=k&-k;
18     }
19 }
20 
21 int query(int k)
22 {
23     int sum=0;
24     while(k>0)
25     {
26         sum+=dat[k];
27         k-=k&-k;
28     }
29     return sum;
30 }
31 
32 void read()
33 {
34     cin>>n;
35     for(int i=1;i<=n;i++)
36     {
37         cin>>a[i];
38     }
39 }
40 
41 void solve()
42 {
43     memset(dat,0,sizeof(dat));
44     cin>>m;
45     int sum=0;
46     int lef=1,rig=1;
47     update(a[1],1);
48     for(int i=0;i<m;i++)
49     {
50         int l,r;
51         cin>>l>>r;
52         while(lef<l)
53         {
54             update(a[lef],-1);
55             sum-=query(a[lef]-1);
56             lef++;
57         }
58         while(lef>l)
59         {
60             lef--;
61             sum+=query(a[lef]-1);
62             update(a[lef],1);
63         }
64         while(rig<r)
65         {
66             rig++;
67             sum+=query(n)-query(a[rig]);
68             update(a[rig],1);
69         }
70         while(rig>r)
71         {
72             update(a[rig],-1);
73             sum-=query(n)-query(a[rig]);
74             rig--;
75         }
76         cout<<sum<<endl;
77     }
78 }
79 
80 int main()
81 {
82     read();
83     solve();
84 }

 

转载于:https://www.cnblogs.com/Leohh/p/7263354.html

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
<p> <strong><span style="background-color:#FFFFFF;color:#E53333;font-size:24px;">本页面购买不发书!!!仅为视频课购买!!!</span></strong> </p> <p> <strong><span style="color:#E53333;font-size:18px;">请务必到</span></strong><a href="https://edu.csdn.net/bundled/detail/49?utm_source=banner"><strong><span style="color:#E53333;font-size:18px;">https://edu.csdn.net/bundled/detail/49</span></strong></a><strong><span style="color:#E53333;font-size:18px;">下单购买课+书。</span></strong> </p> <p> <span style="font-size:14px;">本页面,仅为观看视频页面,如需一并购买图书,请</span><span style="font-size:14px;">务必到</span><a href="https://edu.csdn.net/bundled/detail/49?utm_source=banner"><span style="font-size:14px;">https://edu.csdn.net/bundled/detail/49</span></a><span style="font-size:14px;">下单购买课程+图书!!!</span> </p> <p> <br /> </p> <p> <span style="font-size:14px;">疯狂Python精讲课程覆盖《疯狂Python讲义》全书主体内容。</span> </p> <span style="font-size:14px;">内容包括Python基本数据类型、Python列表、元组和字典、流程控制、函数式编程、面向对象编程、文件读写、异常控制、数据库编程、并发编程与网络编程、数据可视化分析、Python爬虫等。</span><br /> <span style="font-size:14px;"> 全套课程从Python基础开始介绍,逐步步入当前就业热点。将会带着大家从Python基础语法开始学习,为每个知识点都提供对应代码实操、代码练习,逐步过渡到文件IO、数据库编程、并发编程、网络编程、数据分 析和网络爬虫等内容,本课程会从小案例起,至爬虫、数据分析案例终、以Python知识体系作为内在逻辑,以Python案例作为学习方式,最终达到“知行合一”。</span><br />
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值