Forças de código Rodada # 510 (Div. 2) D. Petya e Array

Forças de código Rodada # 510 (Div. 2) D. Petya e Array

Link do tópico

Petya tem uma matriz a consistindo de n inteiros. Ele aprendeu somas parciais recentemente e agora pode calcular a soma dos elementos em qualquer segmento da matriz com muita rapidez. O segmento é uma sequência não vazia de elementos posicionados um ao lado do outro na matriz.

Agora ele se pergunta qual é o número de segmentos em sua matriz com a soma menor que t. Ajude Petya a calcular este número.

Mais formalmente, você deve calcular o número de pares l, r (l≤r) de modo que al + al + 1 + ⋯ + ar <t a_l + a_ {l + 1} + \ cdots + a_r <tumal+umal + 1++umar<t .

Entrada

A primeira linha contém dois inteiros n e t (1≤n≤200000, | t | ≤2e14).

A segunda linha contém uma sequência de inteiros a1, a2,…, an (| ai | ≤1e9) - a descrição do array de Petya. Observe que pode haver elementos negativos, zero e positivos.

Resultado

Imprima o número de segmentos na matriz de Petya com a soma dos elementos menor que t.

Exemplos

entrada

5 4
5 -1 3 4 -1

resultado

5

entrada

3 0
-1 2 -3

resultado

4

entrada

4 -1
-2 1 -2 3

resultado

3

O significado da pergunta é muito simples. Descubra quantos intervalos em 1-n cuja soma é menor que ttt , transformamos ligeiramente:
al + al + 1 +… + ar <t a_l + a_ {l + 1} + \ cdots + a_r <tumal+umal + 1++umar<t
则:
soma [r] - soma [l - 1] <t soma [r] -soma [l-1] <ts u m [ r ]-s u m [ l-1 ]<t
soma [r] - soma [l - 1] ≤ t - 1 soma [r] -sum [l-1] \ leq t-1s u m [ r ]-s u m [ l-1 ]t-1
soma [r] ≤ soma [l - 1] + t - 1 soma [r] \ leq soma [l-1] + t-1s u m [ r ]s u m [ l-1 ]+t-1 A
soma do prefixo pode ser pré-processada e o título é convertido para um certo númeroxxx , encontre menor ou igual ax + t - 1 x + t-1x+t-O número de elementos de 1 , é fácil pensar na árvore de segmento de linha ponderada para encontrar rapidamente o número menor ou igual a um determinado número no intervalo. Este problema deve ser discretizado devido à quantidade de dados. Use umvetor vetorialv e c t o r armazena todas as somas de prefixo, então o subscrito de cada soma de prefixo é o subscrito na árvore de segmento após eles serem separados, então o título é o prefixo e o número de cada prefixo e consulta que atendem às condições. Preste atenção aovetor vetorialOs elementos em v e c t o r devem ser desduplicados, porque a árvore do segmento de linha ponderada retém o estado da última inserção. Se você não desduplicar, a resposta será repetida. O código AC é o seguinte:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+5;
int n,m,k;
ll t,a[N],sum[N],tree[N<<2];
vector<ll>v;
int getpos(ll x){
    
    
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void pushup(int i)
{
    
    
    tree[i]=tree[i<<1]+tree[i<<1|1];
}

void build(int i,int l,int r)
{
    
    
    if(l==r)
    {
    
    
        tree[i]=0;
        return ;
    }
    int mid=l+r>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    pushup(i);
}

void update(int i,int l,int r,int x,int k)
{
    
    
    if(l==r)
    {
    
    
        tree[i]+=k;
        return ;
    }
    int mid=l+r>>1;
    if(x<=mid) update(i<<1,l,mid,x,k);
    else update(i<<1|1,mid+1,r,x,k);
    pushup(i);
}

ll query(int i,int l,int r,int m,int n)
{
    
    
    if(m<=l&&r<=n) return tree[i];
    int mid=l+r>>1;
    ll ans=0;
    if(m<=mid) ans+=query(i<<1,l,mid,m,n);
    if(n>mid) ans+=query(i<<1|1,mid+1,r,m,n);
    return ans;
}

int main(){
    
    
    scanf("%d%lld",&n,&t);
    v.push_back(t-1);
    for(int i=1;i<=n;i++){
    
    
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
        v.push_back(sum[i]);
        v.push_back(sum[i]+t-1);
    }
    if(n==1){
    
    
        if(a[1]<t) printf("1");
        else printf("0");
    }else{
    
    
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        m=v.size();
        build(1,1,m);
        ll ans=0;
        for(int i=n;i>=0;i--){
    
    
            ans+=query(1,1,m,1,getpos(sum[i]+t-1));
            update(1,1,m,getpos(sum[i]),1);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

Acho que você gosta

Origin blog.csdn.net/qq_43765333/article/details/108625256
Recomendado
Clasificación