传送门

参考资料:

  [1]:https://www.cnblogs.com/Miracevin/p/9662350.html

  [2]:https://blog.csdn.net/lengxuenong/article/details/80482202?utm_source=blogxgwz1

  今天已经理解了一晚上了,还是处于懵懵懂懂的状态,明天在肝一天,一定要将自己理解的题解写出来,哇咔咔!

题解

  定义数组 a;

  先将含有 n 个元素的数组 a 离散化,则离散化后的 n 个元素对应 1~n 的某个排列,而我们所要求的就是将离散化后的排列变为 1,2,3,...,n 所需的循环次数。

  对于位置 i ,在这个双向排序过程中,每次 while( ) 循环会把一个 i 之前的大于 i 的数移到 i 后面,并且把一个 i 之后小于 i 的数移到 i 的前面

  for : i  1 to N

    我们可以对于所有的位置 i ,找到[1,i]范围内比 i 小的数的个数 s,i-s 就是 i 位置把小于 i 的放在 i 位置前面,大于 i 的放在 i 位置后面的循环次数。

对红色字体的理解

  冒泡排序,通过交换相邻两数最终使得数组有序;

  对于每个位置 i ,如果比 i 大的数都交换到 i 位置之后,比 i 小的数都交换到 i 位置之前;

  那么,等结束最后一个 i 位置的时候,冒泡排序也就结束了,此时数组也就是有序的。

  因此,对于此题的双向循环,每次判断当前位置 i 需要通过多少次while( )循环才能使得:

  比 i 大的数都交换到 i 位置之后,比 i 小的数都交换到 i 位置之前;

  因此,只需要求出 [1,i] 位置上比 i 大的数的个数,输出最大的那个即是答案;

•Code

 #include<bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
const int maxn=1e5+; int n;
struct Node
{
int val;
int id;
int newVal;
}a[maxn];
//==================BIT=====================
int bit[maxn];
void Add(int x)
{
while(x <= n)
{
bit[x]++;
x += lowbit(x);
}
}
int Sum(int x)
{
int sum=;
while(x > )
{
sum += bit[x];
x -= lowbit(x);
}
return sum;
}
//=======================================
bool cmp(Node _a,Node _b) {//注意,如果val相同,初始编号 id 小的在前
return _a.val < _b.val || (_a.val == _b.val && _a.id < _b.id);
}
bool cmp1(Node _a,Node _b){//将数组恢复到刚开始输入时的状态
return _a.id < _b.id;
}
void Solve()
{
sort(a+,a+n+,cmp);//离散化
for(int i=;i <= n;++i)
a[i].newVal=i;//存储离散化后的值
sort(a+,a+n+,cmp1);
int res=;
for(int i=;i <= n;++i)
{
Add(a[i].newVal);
res=max(res,i-Sum(i));//询问每个位置,找到所需的最大的循环次数
}
printf("%d\n",res);
}
int main()
{
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d",&a[i].val),a[i].id=i;
Solve();
}

•初始疑惑

  将 i 之前的大于 i 的数归位,貌似只用到了问题中的第一个for( ),而并没有用第二个 for( )循环啊;

  那为什么 i-s 就是 i 位置把小于 i 的放在 i 位置前面,大于 i 的放在 i 位置后面的循环次数呢?

我的理解:

  ①如果将 [1,i] 位置中的大于 i 的数全部移到 i 位置后,[i+1,n]位置中的数肯定全部大于 i;

  如果 [i+1,n] 位置存在小于 i 的数,那,[1,i]中肯定存在大于 i 的数,不然,怎么交换呢?

  这样的话,[1,i]位置中大于 i 的数就没有全部移到 i 位置后,与条件①矛盾;

  所以条件①成立;


分割线:2019.7.17

•感想

  当初理解了好长时间的东西到如今成了自然而然地事;

•Code

 #include<bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&-x)
const int maxn=1e5+; int n;
struct Data
{
int v;
int id;
int newV;
}data[maxn];
struct BIT
{
int bit[maxn];
void Init()
{
memset(bit,,sizeof(bit));
}
void add(int t)
{
while(t < maxn)
{
bit[t]++;
t += lowbit(t);
}
}
int Sum(int t)
{
int sum=;
while(t > )
{
sum += bit[t];
t -= lowbit(t);
}
return sum;
}
}_bit; ///树状数组求逆序对时,v相同的一定要让编号小的在前
bool cmp1(Data a,Data b)
{
if(a.v != b.v)
return a.v < b.v;
return a.id < b.id;
}
bool cmp2(Data a,Data b)
{
return a.id < b.id;
}
int Solve()
{
sort(data+,data+n+,cmp1);
for(int i=;i <= n;++i)
data[i].newV=i;
sort(data+,data+n+,cmp2); _bit.Init();
int ans=;
for(int i=;i <= n;++i)
{
_bit.add(data[i].newV);
ans=max(ans,i-_bit.Sum(i));
} return ans;
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
scanf("%d",&n);
for(int i=;i <= n;++i)
{
scanf("%d",&data[i].v);
data[i].id=i;
}
printf("%d\n",Solve()); return ;
}

洛谷 P4375 [USACO18OPEN]Out of Sorts G(树状数组求冒泡排序循环次数加强版)的更多相关文章

  1. 洛谷 P4378 [USACO18OPEN]Out of Sorts S(树状数组求冒泡排序循环次数)

    传送门:Problem P4378 https://www.cnblogs.com/violet-acmer/p/9833502.html 要回宿舍休息了,题解明天再补吧. 题解: 定义一数组 a[m ...

  2. 洛谷 P1908 逆序对 Label:归并排序||树状数组 不懂

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...

  3. 【洛谷P1972】HH的项链 离线+树状数组

    题目大意:静态查询序列区间颜色数. 题解:对于一个查询区间 [l , r] ,若有两个相同颜色的点在这个区间中,则总是取下标靠近端点 r 的颜色计入答案贡献.对于每个下标,记录下在这个下标之前,且距离 ...

  4. 洛谷 P3616 富金森林公园题解(树状数组)

    P3616 富金森林公园 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积水也有 ...

  5. 洛谷P3312 [SDOI2014]数表(莫比乌斯反演+树状数组)

    传送门 不考虑$a$的影响 设$f(i)$为$i$的约数和 $$ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^nf(gcd(i,j))$$ $$=\sum\limi ...

  6. 洛谷P3250 [HNOI2016]网络(整体二分+树状数组+树剖)

    传送门 据说正解是树剖套堆???然而代码看着稍微有那么一点点长…… 考虑一下整体二分,设当前二分到的答案为$mid$,如果所有大于$mid$的边都经过当前点$x$,那么此时$x$的答案必定小于等于$m ...

  7. 洛谷P3810-陌上开花(三维偏序, CDQ, 树状数组)

    链接: https://www.luogu.org/problem/P3810#submit 题意: 一个元素三个属性, x, y, z, 给定求f(b) = {ax <= bx, ay < ...

  8. 洛谷 P1972 [SDOI2009]HH的项链(树状数组,离线)

    传送门 解题思路 因为是求区间的不同种类数,所以我们用树状数组(貌似并没有什么直接联系) (...表示到) 还是和原来一样,用s[i]来表示a[i-lowbit(i)]...a[i]的种类数. 因为有 ...

  9. 洛谷P1972 [SDOI2009]HH的项链(树状数组)

    题目链接: https://www.luogu.org/problemnew/show/P1972 题目描述: HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后 ...

随机推荐

  1. apacheTomcat

    Window+R ------>cmd || Window PowerShell apacheTomcat\bin> ./startup.sh

  2. Week3 关于“微软必应词典客户端”的案例分析

    第一部分  调研,评测 一.iphone客户端的bug挖掘: 1.在例句中点击单词或短语,如果这个时候点得稍微快了一点,关联相应的翻译时会出现混乱. 经过调查发现,这个bug应该是必应得一个全平台错误 ...

  3. Atlas & mysql-proxy

    Atlas https://github.com/Qihoo360/Atlas https://github.com/Qihoo360/Atlas/wiki/Installing-Atlas Atla ...

  4. php实现常驻进程 多进程监控

    php都是通过crontabd定时脚本处理队列的,面试被问到php如何常驻进程进行处理队列,想了半天这样不知道是否是一种方式 <?php function logs(){ file_put_co ...

  5. [转帖]以Windows服务方式运行.NET Core程序

    以Windows服务方式运行.NET Core程序 原作者blog:https://www.cnblogs.com/guogangj/p/10093102.html 里面使用了NSSM 工具 但是自己 ...

  6. [转帖] securebootthemes 挖矿病毒的说明 http://blog.netlab.360.com/msraminer-qian-fu-yi-jiu-de-wa-kuang-jiang-shi-wang-luo/ 原文为毛不给一个专杀工具呢.

    MsraMiner: 潜伏已久的挖矿僵尸网络 2017 年 11 月底,我们的 DNSMon 系统监测到几个疑似 DGA 产生的恶意域名活动有异常.经过我们深入分析,确认这背后是一个从 2017 年 ...

  7. YII2十三大特性2

    第十三 场景(scenario)的使用 例如:有三个场景,分别为创建,更新,确认回款 首先,定义所有的场景,及规则,如下所示: <?php namespace core\models; use ...

  8. Mysql 悲观锁

    转载:http://chenzhou123520.iteye.com/blog/1860954 悲观锁介绍: 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处 ...

  9. ansible系列6-用户管理

    第一种:新增用户 ansible host -m user -a "name=zhang shell=/bin/bash groups=admin,root append=yes home= ...

  10. 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)

    洛谷题目传送门 闲话 看完洛谷larryzhong巨佬的题解,蒟蒻一脸懵逼 如果哪年NOI(放心我这样的蒟蒻是去不了的)又来个决策单调性优化DP,那蒟蒻是不是会看都看不出来直接爆\(0\)?! 还是要 ...