zoukankan      html  css  js  c++  java
  • #41. 新斯诺克

    Description

    内部题目,不放链接了。

    Solution

    题意大概就是让求平均数大于 (m) 的子段的个数。

    很容易想到前缀和,但是这个前缀和该怎么用呢?

    我们可以先把 (a) 序列每个数都减去 (m) 之后在做前缀和。

    这样判断一个子段是否合法只需要判断子段和是否大于 0,即可。

    暴力枚举的话是 (O(n^2)) 的,无法通过此题。

    仔细分析我们需要的条件 (sum_i - sum_j > 0 (i > j))

    诶,这不就是个二维正序嘛。

    于是拿个树状数组维护即可。

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define ll long long
    
    using namespace std;
    
    const ll N = 1e6 + 10;
    ll n, m, ans;
    ll c[N];
    struct node{
    	ll a, b;
    	bool operator < (const node &t) const{
    		return a != t.a ? a < t.a : b > t.b;
    	}
    }p[N];
    
    inline void update(ll x, ll y){
    	for(; x <= n; x += (x & -x))
    		c[x] += y;
    }
    
    inline ll query(ll x){
    	ll res = 0;
    	for(; x > 0; x -= (x & -x))
    		res += c[x];
    	return res;
    }
    
    signed main(){
    	scanf("%lld%lld", &n, &m);
    	for(ll i = 1; i <= n; i++){
    		scanf("%lld", &p[i].a);
    		p[i].a = p[i - 1].a + p[i].a - m;
    		ans += (p[i].a > 0);
    		p[i].b = i;
    	}
    	sort(p + 1, p + 1 + n);
    	for(ll i = 1; i <= n; i++){
    		update(p[i].b, 1);
    		ans += query(p[i].b - 1);
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15336072.html

  • 相关阅读:
    ie下如果已经有缓存,load方法的效果就无法执行.的解决方法
    css公共样式
    pageX、pageY全兼容
    js滚动加载插件
    getComputedStyle()与currentStyle
    excel15个技巧
    XMLHttpRequest函数
    继承模式
    cookie函数
    jQuery添加删除元素
  • 原文地址:https://www.cnblogs.com/xixike/p/15336072.html
Copyright © 2011-2022 走看看