洛谷P2717 寒假作业

题目:https://www.luogu.org/problemnew/show/2717

题目背景

zzs和zzy正在被寒假作业折磨,然而他们有答案可以抄啊。

题目描述

他们共有n项寒假作业。zzy给每项寒假作业都定义了一个疲劳值Ai,表示抄这个作业所要花的精力。zzs现在想要知道,有多少组连续的寒假作业的疲劳值的平均值不小于k?

简单地说,给定n个正整数A1,A2,A3,...,An,求出有多少个连续的子序列的平均值不小于k。

输入输出格式

输入格式:

 

第一行两个正整数,n和k。

第二行到第n+1行,每行一个正整数Ai。

 

输出格式:

 

一个非负整数。

 

输入输出样例

输入样例#1: 
3 2
1
2
3
输出样例#1: 
4

说明

样例解释:共有6个连续的子序列,分别是(1)、(2)、(3)、(1,2)、(2,3)、(1,2,3),平均值分别为1、2、3、1.5、2.5、2,其中平均值不小于k的共有4个。

对于20%的数据,1<=n<=100;

对于50%的数据,1<=n<=5000;

对于100%的数据,1<=n<=100000;

对于100%的数据,1<=Ai<=10000,1<=k<=10000。

 

解析

20分的话,枚举区间挨个算吧(~ ̄▽ ̄)~

50分的话,算个前缀和,枚举区间挨个算吧(~ ̄▽ ̄)~

100分怎么办?(⊙ω⊙)

是不是什么奇葩的数据结构呢?Σ( ° △ °|||)︴

反正蒟蒻我没想出来-_-!

但,我可以乱搞啊(~ ̄▽ ̄)~。

感觉那个k很烦人,我们转化一下,让每个数减k。

这样就转化成求大于等于0的区间啦。

我们不是还用过前缀和吗?那我这地方也可以用一次啦。

设s[i]代表a[i]-k的前缀和,那么,

如果i<j,且s[i]<s[j],那么区间i+1~j便是合法的喽。

有没有熟悉,有没有想到什么?(⊙ω⊙)

对啦,求逆序对哦不正序对= ̄ω ̄=

求正序对的方法和求逆序对的方法是相似的喽(~ ̄▽ ̄)~

这道题就完成啦。

warning:为什么我总是比答案少啊-_-!

tips:这不完全是逆序对啦( ﹁ ﹁ ) ~→

          你需要考虑单个元素啦( ﹁ ﹁ ) ~→

           单个元素若比0大答案也要+1啦( ﹁ ﹁ ) ~→

warning:为什么我会wa-_-!

tips:开long long( ﹁ ﹁ ) ~→

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 #define maxn 100100
 8 #define ll long long
 9 int a[maxn],s[maxn];
10 int tmp[maxn];
11 int n,k;
12 ll ans;
13 void merge(int l,int m,int r){
14     int i=l,j=m+1,k=l;
15     while (i<=m&&j<=r){
16         if (s[i]<=s[j]){
17             ans+=r-j+1; 
18             tmp[k++]=s[i++];
19         }else{
20             tmp[k++]=s[j++];
21         }
22     }
23     while (i<=m) tmp[k++]=s[i++];
24     while (j<=r) tmp[k++]=s[j++];
25     for (int gg=l;gg<=r;++gg){
26         s[gg]=tmp[gg];
27     }
28 }
29 void merge_sort(int l,int r){
30     int m=(l+r)>>1;
31     if (l<r){
32         merge_sort(l,m);
33         merge_sort(m+1,r);
34         merge(l,m,r);
35     }
36 }
37 int main(){
38     scanf("%d%d",&n,&k);
39     for (int i=1;i<=n;++i){
40         scanf("%d",&a[i]);
41         s[i]=s[i-1]+a[i]-k;
42     }
43     merge_sort(0,n); //一定不要忘了单个元素情况
44     printf("%lld",ans);
45     return 0;
46 }
View Code

 

posted @ 2017-11-07 16:17  lonlyn  阅读(233)  评论(1编辑  收藏  举报