Codevs3324 新斯诺克
来源:互联网 发布:硅藻泥排行榜 知乎 编辑:程序博客网 时间:2024/04/27 19:06
题目大意:给定一个具有n个数的数列和一个数m,求有多少个连续子序列的和的平均数大于m。
思路:平均数是不用管的,数列中每个数直接减去即可,这样条件转化为连续子序列的和大于0。再由此联想到数组的前缀和,则某一段序列和a[i]+…+a[j]=s[j]-s[i-1],符合条件的话,则有s[j]-s[i-1]>0,即s[j]>s[i-1],由此转化为求逆序对数。
代码如下:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=100005;long long n,m,s[maxn],res=0,c[maxn];void init(){ memset(s,0,sizeof(s)); scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) { int tmp; scanf("%d",&tmp); s[i]=s[i-1]+tmp-m; }}void msort(int l,int r){ if (l==r) { c[l]=s[l]; return; } int mid=(l+r)/2; msort(l,mid); msort(mid+1,r); int i=l,j=mid+1,k=l; while (i<=mid && j<=r) { if (s[i]>=s[j]) { c[k]=s[j]; res+=(mid-i+1); j++; k++; } else { c[k]=s[i]; i++; k++; } } while (i<=mid) { c[k]=s[i]; i++; k++; } while (j<=r) { c[k]=s[j]; j++; k++; } for (int i=l;i<=r;++i) s[i]=c[i];}int main(){ init(); msort(0,n); n++; long long ans=n*(n-1)/2; printf("%lld",ans-res); return 0;}
0 0
- Codevs3324 新斯诺克
- [codevs3324]新斯诺克(树状数组)
- 【基础练习】【归并逆序对】codevs3324 新斯诺克题解
- 【codevs3324】新斯洛克
- 新斯诺克
- 新斯诺克
- Codevs P3324 新斯诺克
- 【u249】新斯诺克
- Codevs 3324 新斯诺克
- codevs.3324 新斯诺克
- 新斯诺克(sheeta.pas/c/cpp)
- 【复赛模拟试题】新斯诺克 逆序对
- 20160317 CodeVS 1025 选菜,1102 采药,3324 新斯诺克
- 斯诺克名词解释
- 斯诺克规则
- 斯诺克 术语
- 斯诺克 Snooker
- 斯诺克规则简介
- NOIP2013 表达式求值
- 多线程出现的问题
- Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息
- 字节流与字符流的区别
- POJ 1837 Balance(DP)
- Codevs3324 新斯诺克
- jQuery使用serializeArray()方法取得表单数据并附加json数据
- kafka数据保存时间问题与kafka的性能测试
- Ubuntu 配置 JDK 环境变量
- 释放出来
- Java中Timer的学习笔记(一)
- Lake Counting 水洼算法
- iOS每日一记之——————键盘被挡 自动试图上滚
- Toast 的使用1