hdu--4911--归并排序||树状数组

发现一个小小的 逆序数里真的藏了好多东西啊=-=

解决这题 你需要知道一点...

对于一串给定的数字 我随便写一串吧..

index:   0  1  2  3  4

value: 4  8  7  5  6    这时候 总的逆序对数是  3+2=5   假如我们只能进行相邻元素的交换 这最好情况是什么呢?

那肯定就是假如本来 arr[x]>arr[x+1] 那这样是形成一个逆序数的吧 我们将它进行交换 这样就少了一个逆序数对是吧...

但是 对于其它位置的元素是没有影响的对吧

所以 我们需要的最小次数呢 就是sum<即原数组的逆序数个数> 然后把它和k比较下大小就是了

看到了disucss里面的帖子 才第一次 知道 sort是不稳定的排序...这题里要用stable_sort。。没用树状数组去写-呆会写

每天mhxy 和lol 玩来玩去  超累啊=-=

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 typedef long long LL;
 6 LL sum;
 7 const int size = 100010;
 8 int arr[size];
 9 int temp[size];
10
11 void merge_sort( int l , int r )
12 {
13     int mid , p , q , i;
14     if( r-l > 1 )
15     {
16         mid = l + (r-l) / 2;
17         p = l;
18         q = mid;
19         i = l;
20         merge_sort( l , mid );
21         merge_sort( mid , r );
22         while( p<mid || q<r )
23         {
24             if( q>=r || (p<mid && arr[p] <= arr[q] ) )
25             {
26                 temp[i++] = arr[p++];
27             }
28             else
29             {
30                 temp[i++] = arr[q++];
31                 sum += (mid-p);
32             }
33         }
34         for( i = l ; i<r ; i++ )
35         {
36             arr[i] = temp[i];
37         }
38     }
39 }
40
41 int main()
42 {
43     cin.sync_with_stdio(false);
44     int n;
45     LL k;
46     while( cin >> n >> k )
47     {
48         sum = 0;
49         for( int i = 0 ; i<n ; i++ )
50         {
51             cin >> arr[i];
52         }
53         merge_sort( 0 , n );
54         cout << max( sum-k , (LL)0 ) << endl;
55     }
56     return 0;
57 }

这边要注意下 0的前面要用LL进行强制转换 不然会CE..因为前者是LL类型的..

做逆序数对的时候 很容易会是用到64位的 因为 假如给你这么组BT数组  X , X-1 , X-2 , X-3 , …………x-i,x-i-1,…………,1  那就是Ah 等差数列求和#24.。

这边留一大片空白 给待会写的 树状数组....

突然 想再写点关于刚刚的归并排序的一些东西<因为我觉得归并很难啊 我最烦这种递归的了 卧槽..真羡慕那些写递归和写for一样的人..#80>

似乎 归并排序的 分治操作将它不断进行二分的操作 最终在分成只有一个元素的时候 结束了递归

然后开始一步步从结束递归的那个函数慢慢地回去向上操作.  可能 我们将  2 1 4 3 这4个元素 进行归并操作 那么我们是这样进行的吧

<2,1,4,3>---><2,1> , <4,3>       <2,1>----><2.>,<1.>       <4,3>----><4,>,<3>

先是要比较 2 和 1的大小关系 1小于2 那么先复制右边空间的数组  这里的左右以 Mid 为分界线  同时 如果是要进行逆序数对数个数统计的操作 那么这时候就需要mid-p了来计算此时左空间总共的数据个数这边不用担心会重复计算 因为当你左右空间全部遍历结束以后 它就会进行合并操作了 一起算到上一个更大的左/右区间之一了

--------恩 好像就暂时自己能想到这些地方吧 可能有错误 不可尽信 ..

不得不吐槽下 在写下上述东西的时候 垃圾电信 网断了大概6 7次 我草了...

时间: 2024-10-01 13:37:29

hdu--4911--归并排序||树状数组的相关文章

HDU 4911 Inversion 树状数组求逆序数对

显然每次交换都能降低1 所以求出逆序数对数,然后-=k就好了.. . _(:зゝ∠)_ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<set> #include<map> #include<iostream> #include<algorithm> using namespace std; #define N 100005 #define

HDU Cow Sorting (树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cow

hdu 5193 分块 树状数组 逆序对

题意: 给出n个数,a1,a2,a3,...,an,给出m个修改,每个修改往数组的某个位置后面插入一个数,或者把某个位置上的数移除.求每次修改后逆序对的个数. 限制: 1 <= n,m <= 20000; 1 <= ai <= n 思路: 插入和删除用分块来处理,块与块之间用双向链表来维护,每一块用树状数组来求小于某个数的数有多少个. 外层可以使用分块维护下标,这样添加和删除元素的时候,也很方便,直接暴力.查找权值个数时,使用树状数组比较方便.内层通过树状数组维护权值. 每次更新即

UVA 11990 `Dynamic&#39;&#39; Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3141 题意 一个1到n的排列,每次随机删除一个,问删除前的逆序数 思路 综合考虑,对每个数点,令value为值,pos为位置,time为出现时间(总时间-消失时间),明显是统计value1 > value2, pos1 < pos2, time1 < time2的个

HDU 5493 Queue 树状数组

Queue Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5493 Description N people numbered from 1 to N are waiting in a bank for service. They all stand in a queue, but the queue never moves. It is lunch time now,

hdu 4455 Substrings(树状数组+递推)

题目链接:hdu 4455 Substrings 题目大意:给定一个长度为N的序列,现在有Q次询问,每次给定一个w,表示长度,输出序列中长度为w的连续子序列 的权值和.序列的权值表示序列中不同元素的个数. 解题思路:递推,先预处理处每个位置和前面相同的数据的最短距离P.dp[i]表示说长度为i子序列的权值和,dp[i+1] = dp[i] + v - c.v为[i+1~N]中P值大于i的个数,我们可以看作将长度为i的子序列长度向后增加1,那么v则为增加长度带来 的权值增加值,c则是最后一个长度为

POJ 2352 &amp;&amp; HDU 1541 Stars (树状数组)

一开始想,总感觉是DP,可是最后什么都没想到.还暴力的交了一发. 然后开始写线段树,结果超时.感觉自己线段树的写法有问题.改天再写.先把树状数组的写法贴出来吧. ~~~~~~~~~~~~~~~~~~~~~~~~ 树状数组不懂的去看刘汝佳的大白书,那个图画得很清楚. 题目大意:星星的坐标以y递增的顺序给出,这些点的左下方的点数代表这个点的级数,问0~N-1的级数有多少个?其实y根本木有用. 题目链接:http://poj.org/problem?id=2352 http://acm.hdu.edu

nyist oj 117 求逆序数 (归并排序&amp;&amp;树状数组)

求逆序数 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数是多少. 比如 1 3 2 的逆序数就是1. 输入 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整

hdu 4031(树状数组+辅助数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4031 Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 1890    Accepted Submission(s): 554 Problem Description Today is the 10th Annual of "S

HDU 2689Sort it 树状数组 逆序对

Sort it Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4110    Accepted Submission(s): 2920 Problem Description You want to processe a sequence of n distinct integers by swapping two adjacent s