逆序对&归并排序:新斯诺克

题目描述 

Description

斯诺克又称英式台球,是一种流行的台球运动。在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄、绿、棕、蓝、粉红、黑)共22个球。

击球顺序为一个红球、一个彩球直到红球全部落袋,然后以黄、绿、棕、蓝、粉红、黑的顺序逐个击球,最后以得分高者为胜。斯诺克的魅力还在于可以打防守球,可以制造一些障碍球使对方无法击打目标球而被扣分。正是因为这样,斯诺克是一项充满神奇的运动。

现在考虑这样一种新斯诺克,设母球(母球即是白球,用于击打其他球)的标号为M,台面上有N 个红球排成一排,每一个红球都有一个标号,他们的标号代表了他们的分数。

现在用母球击打这些红球,一杆击打,如果母球接触到红球,就称为“K 到红球”。我们假设,一次可以击打任意多相邻连续的红球,也可以只击打一个球。并且红球既不会落袋,也不会相互发生碰撞,而只是停留在原处。每次击打时候,要想“K 到红球”,至少要击打一个红球,如果想一次击打多个红球,那么击打的红球必须是依次连续排列的。如果一次“K 到红球”所有红球的标号之和的平均数大于母球的标号M,就获得了一个“连击”。

现在请你计算总共能有多少种“连击”方案。

注意:如果当前有标号为1、2、3 的三种红球,母球标号为0,有如下6 种获得“连击”方案:( 1)、( 2)、( 3)、( 1,2)、( 2,3)、( 1,2,3)

输入描述 Input Description

共有两行。

第一行是N,M (N<=100000,M<=10000) ,N 表示台面上一共有N 个红球,M 表示母球的标号。

第二行是N 个正整数,依次表示台面上N 个红球的标号,所有标号均不超过10000。

输出描述 Output Description

只有一个数,为“连击”的方案总数。

样例输入 Sample Input

4 3

3 7 2 4

样例输出 

Sample Output

7

在i+1到j的区间上假设成立;(sum[j]-sum[i])/(j-i)>msum[j]-sum[i]>(j-i)*msum[j]-sum[i]>m*j-m*im*i-sum[i]>m*j-sum[j]

设A[i]=m*i-sum[i];A[i]>A[j],则连击成立。

******i=0时,A[i]=0;*****变量都为int64;

code:
var init,r,sum:array[0..10000]of longint;    i,j,k:longint;    n,m,ans:longint;
procedure msort(s,t:longint);          var m,i,j,k:longint;          begin if s=t then exit;                m:=(s+t) div 2;                msort(s,m);                msort(m+1,t);                i:=s; j:=m+1; k:=s;                while (i<=m)and(j<=t) do                      begin if init[i]>init[j]                               then begin r[k]:=init[i];
                                          ans:=ans+m-i+1;                                         inc(k);                                         inc(i);                                    end                               else begin r[k]:=init[j];                                          inc(k);                                          inc(j);                                    end;                      end;                while i<=m do                      begin r[k]:=init[i];                            inc(k);                            inc(i);                      end;                while j<=t do                      begin r[k]:=init[j];                            inc(k);                            inc(j);                      end;                for i:=s to t do                    init[i]:=r[i];          end;
begin readln(n,m);      fillchar(init,sizeof(init),0);      fillchar(sum,sizeof(sum),0);      fillchar(r,sizeof(r),0);      init[0]:=0;      for i:=1 to n do          begin read(init[i]);                sum[i]:=sum[i-1]+init[i];          end;      for i:=0 to n do          init[i]:=m*i-sum[i];      ans:=0;      init[0]:=0;      {      for i:=0 to n do          write(init[i],‘ ‘);      writeln;      }      msort(0,n);      writeln(ans);end.
时间: 2024-08-04 18:31:56

逆序对&归并排序:新斯诺克的相关文章

Codevs 3324 新斯诺克

时间限制: 1 s  空间限制: 64000 KB  题目等级 : 白银 Silver 题目描述 Description 现在考虑这样一种新斯诺克,设母球(母球即是白球,用于击打其他球)的标号为M,台面上有N 个红球排成一排,每一个红球都有一个标号,他们的标号代表了他们的分数. 现在用母球击打这些红球,一杆击打,如果母球接触到红球,就称为“K 到红球”.我们假设,一次可以击打任意多相邻连续的红球,也可以只击打一个球.并且红球既不会落袋,也不会相互发生碰撞,而只是停留在原处.每次击打时候,要想“K

Codevs3324 新斯诺克

题目描述 Description 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄.绿.棕.蓝.粉红.黑)共22个球. 击球顺序为一个红球.一个彩球直到红球全部落袋,然后以黄.绿.棕.蓝.粉红.黑的顺序逐个击球,最后以得分高者为胜.斯诺克的魅力还在于可以打防守球,可以制造一些障碍球使对方无法击打目标球而被扣分.正是因为这样,斯诺克是一项充满神奇的运动. 现在考虑这样一种新斯诺克,设母球(母球即是白球

算法-逆序对(归并排序)

我觉得每次博客时,开头的话语是最难写的,这次就不写了,但是要鼓励自己好好学习! 题意: 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个 逆序对.给你一个数组,求出这个数组中逆序对的总数. 概括:如果a[i] > a[j] 且 i < j, a[i] 和 a[j] 构成一个逆序对. 样例: 序列 [2, 4, 1, 3, 5] 中,有 3 个逆序对 (2, 1), (4, 1), (4, 3),则返回 3 这题理解起来不是很难的,但是麻烦的地方就是时间复杂度.如果用常规的

洛谷P1908 求逆序对 [归并排序]

题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游 戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>aj且i<j的有序对.知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目. 输入输出格式 输入格式: 第一行,一个数n,表示序列中有n个数. 第二行n个数,表示给定的序列. 输出格式: 给定序列中逆序对的数目. 输入输出样例

[剑指offer]51-数组中的逆序对(归并排序)

题目链接 https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5 题意 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007.题目保证输入的数组中没有的相同的数字. 解题思路 在归并排序的过程中计逆序对.时间复杂度O(nlogn),空间复杂度O(n). 将

新斯诺克

[题目描述] 设母球(母球即是白球,用于击打其他球)的标号为M,台面上有N 个红球排成一排,每一个红球都有一个标号,他们的标号代表了他们的分数. 现在用母球击打这些红球,一杆击打,如果母球接触到红球,就称为“K 到红球”.我们假设,一次可以击打任意多相邻连续的红球,也可以只击打一个球.并且红球既不会落袋,也不会相互发生碰撞,而只是停留在原处.每次击打时候,要想“K 到红球”,至少要击打一个红球,如果想一次击打多个红球,那么击打的红球必须是依次连续排列的.如果一次“K 到红球”所有红球的标号之和的

逆序对

什么是逆序对?? 我们在这里给出一个定义:如果i<j&&a[i]>a[j]的一对数称为逆序对. 为什么??!! 背过!!(都说了是定义了!)(其实我也不知道为什么  orz   (*^__^*) ……) 但是知道逆序对有什么用处呢? 具体用处我也不是很清楚,但是目前我们可以用逆序对的个数求将一列数排成有序的一列数交换的次数 怎样求逆序对呢?? 我们在这里给出两种算法:归并排序求逆序对:树状数组求逆序对. §归并排序求逆序对 归并排序的核心思想是二分. 我们将一个序列a1,a2,

归并排序&amp;&amp;逆序对(codves1688,4163)

归并排序 归并排序采用的是分治的思想 1.划分问题:把序列分为元素个数尽量相等的两半 2.递归求解:把两半分别排序 3.合并问题:把两个有序的序列合并为一个 对于第三个问题,我们可以从两个序列中最小的元素开始比较,把较小的加入新的队列中,直到某个序列为空,把另外的一个序列直接加入,然后将原来的序列覆盖.其实很简单,下面看看模板代码 写得烂,不要在意(⊙o⊙)-: 这个就是归并排序(⊙o⊙)-,本人感觉很简单的,归并排序好像比sort,快排的复杂度低,也就是说快一点,是NlogN的复杂度.既然说了

codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)

题目链接: C. Mashmokh and Reverse Operation time limit per test 4 seconds memory limit per test 512 megabytes input standard input output standard output Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university