传送门

参考资料:

  [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. Gitblit版本服务器环境部署记录

    Gitblit介绍Gitblit 是一个纯 Java 库用来管理.查看和处理 Git 资料库.相当于 Git 的 Java 管理工具,支持linux系统.Git是分布式版本控制系统,它强调速度.数据一 ...

  2. Scrum Meeting day 4

                第四次会议 No_00:工作情况 No_01:任务说明 待完成 已完成 No_10:燃尽图 No_11:照片记录 待更新 No_100:代码/文档签入记录 No_101:出席表 ...

  3. 2-Twenty First Scrum Meeting-20151221

    任务安排 成员 今日完成 明日任务 闫昊 请假(数据库)   唐彬 请假(数据库)   史烨轩  尝试使用downloadmanager对notification进行更新  尝试使用downloadm ...

  4. 《Linux内核分析》期终总结&《Linux及安全》期中总结

    <Linux内核分析>期终总结&<Linux及安全>期中总结 [李行之 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc. ...

  5. Linux内核分析第五周学习总结

    扒开系统调用的三层皮(下) 20135237朱国庆+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...

  6. Filter(转载)

    web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...

  7. Java解析Excel

    前两天总结了些关于Excel和CSV结合TestNG进行数据驱动测试的例子,对于Excel存放TestCase和关键字如何进行解析,也做了对应的总结,希望在学习的路上勇往直前,有不对的地方,希望大家指 ...

  8. ASP.NET MVC布局

    一.Views文件夹 -> Shared文件夹下的 _Layout.cshtml 母版页 @RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合 ...

  9. 使用kindeditor来替换ecshop的fckeditor编辑器,让ecshop可以批量上传图片

    老杨原创 kindeditor此编辑器可以让ecshop批量上传图片,可以插入代码,可以全屏编辑,可以插入地图.视频,进行更多word操作,设置字体. 步骤一:进入kindeditor的官网,http ...

  10. [转帖].NET Core 2.0 是您的最好选择吗?

    .NET Core 2.0 是您的最好选择吗? https://www.cnblogs.com/vipyoumay/p/7388371.html 1. NET Core 2.0 是您的最好选择吗? 1 ...