Always keep a beginner's mi|

luckydrawbox

园龄:4个月粉丝:1关注:2

P2804 神秘数字

Link\text{Link}

福利

双倍经验

题意

一个长度为 nn 的区间 a1na_{1\sim n},求其中有多少个连续子序列的平均数大于 mm?答案对 9208493192084931 取模。

分析

首先我们知道:对于一个区间,如果每个数都减去 mm,那么这个区间的平均数就会减少 mm;同时,它的任意连续子区间的平均数都会减少 mm

既然这样,我们只需要令整个区间都减少 mm,于是问题就转化成了:

一个长度为 nn 的区间 a1na_{1\sim n},求其中有多少个连续子序列的平均数大于 00?答案对 9208493192084931 取模。

既然一个连续子区间的平均数大于 00 ,那么这个连续子区间的和也大于 00,于是问题又简化了:

一个长度为 nn 的区间 a1na_{1\sim n},求其中有多少个连续子序列的和大于 00?答案对 9208493192084931 取模。

求和部分显然可以用前缀和计算 si=j=1iaj=si1+ais_i=\sum_{j=1}^i a_j=s_{i-1}+a_i 来解决(特别地,s0=0s_0=0),一个区间和 [i,j][i,j] 可以转化为 sjsi1s_j-s_{i-1},问题再次变形:

一个长度为 n+1n+1 的区间 s0ns_{0\sim n},求其中有多少对 i,j(1i<jn)i,j(1\le i<j\le n) 使 sjsi1>0s_j-s_{i-1}>0?答案对 9208493192084931 取模。

sjsi1>0s_j-s_{i-1}>0 显然相当于 si1<sjs_{i-1}<s_j,所以其实我们要求的就是顺序对(就是把逆序对反过来求)。

求顺序对的方法很多,这里提供一个值域分块做法,貌似比权值线段树好写一点。

代码

时间复杂度 O(nn)O(n\sqrt n),空间复杂度 O(n)O(n)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long read(){
    long long x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
void write(long long x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
const int N=2e5+10;
const ll mod=92084931;
int n;
ll m,a[N],s[500],len,v[N],sum;
int discrete(int n,ll *a){
    int b[N];
    for(int i=1;i<=n;i++)
        b[i]=a[i];
    sort(b+1,b+n+1);
    int tot=unique(b+1,b+n+1)-(b+1);
    for(int i=1;i<=n;i++)
        a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
    return tot;
}
ll ask(int w){
	int k=w/len;
	ll ans=0;
	for(int i=0;i<k;i++)
		ans=(ans+s[i])%mod;
	for(int i=k*len;i<w;i++)
		ans=(ans+v[i])%mod;
	return ans;
}
void add(int w){
	v[w]++;
	s[w/len]++;
}
int main(){
	n=read()+1;m=read();//把下标从2开始统计,这样方面在前面插入0 
	for(int i=2;i<=n;i++)
		a[i]=read()-m+a[i-1];//把a数组直接当前缀和用 
	int tot=discrete(n,a);//离散化 
	len=sqrt(tot);
	add(a[1]);//插入0 
	for(int i=2;i<=n;i++){
		sum=(sum+ask(a[i]))%mod;
		add(a[i]);
	}
	write(sum);
    return 0;
}

本文作者:luckydrawbox

本文链接:https://www.cnblogs.com/luckydrawbox/p/18526590

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   luckydrawbox  阅读(7)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起