zoukankan      html  css  js  c++  java
  • Loj#6278. 数列分块入门 2

    给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值c^2的元素个数。

    样例输入

    4
    1 2 2 3
    0 1 3 1
    1 1 3 2
    1 1 4 1
    1 2 3 2

    样例输出

    3
    0
    2
    分析:复习了一下分块.
       对于修改操作,在整块外的直接暴力修改,否则给每个块维护一个修改标记. 这样每个元素的最终值就是它本身 + 它所属块的修改标记.
       对于查询操作,整块外的暴力统计,整块内的需要给每一块排序,二分即可.
       几个易错点:
       1.不要直接排序原序列.
       2.注意序列的下标和块的下标不要弄混了.
       3.如果修改的区间在一个整块内,则直接暴力修改.
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const ll maxn = 50010;
    ll n,block,pos[maxn],l[maxn],r[maxn],cnt,a[maxn],add[maxn];
    vector <ll> b[maxn];
    
    void Sort(int x)
    {
        b[x].clear();
        for (int i = l[x]; i <= r[x]; i++)
            b[x].push_back(a[i]);
        sort(b[x].begin(),b[x].end());
    }
    
    void update(ll L,ll R,ll x)
    {
        if (pos[L] == pos[R])
        {
            for (ll i = L; i <= R; i++)
                a[i] += x;
            Sort(pos[L]);
            return;
        }
        for (ll i = pos[L] + 1; i <= pos[R] - 1; i++)
            add[i] += x;
        for (ll i = L; i <= r[pos[L]]; i++)
            a[i] += x;
        for (ll i = l[pos[R]]; i <= R; i++)
            a[i] += x;
        Sort(pos[L]);
        Sort(pos[R]);
    }
    
    ll query(ll L,ll R,ll x)
    {
        ll res = 0;
        if (pos[L] == pos[R])
        {
            for (ll i = L; i <= R; i++)
                if (a[i] + add[pos[i]] < x)
                    res++;
            return res;
        }
        for (ll i = L; i <= r[pos[L]]; i++)
            if (a[i] + add[pos[i]] < x)
                res++;
        for (ll i = l[pos[R]]; i <= R; i++)
            if (a[i] + add[pos[i]]< x)
                res++;
        for (ll i = pos[L] + 1; i <= pos[R] - 1; i++)
        {
            int temp = x - add[i];
            res += lower_bound(b[i].begin(),b[i].end(),temp) - b[i].begin();
        }
        return res;
    }
    
    int main()
    {
        freopen("test.txt","r",stdin);
        scanf("%lld",&n);
        block = sqrt(n);
        for (ll i = 1; i <= n; i++)
        {
            scanf("%lld",&a[i]);
            pos[i] = (i - 1) / block + 1;
            b[pos[i]].push_back(a[i]);
        }
        cnt = (n - 1) / block + 1;
        for (ll i = 1; i <= cnt; i++)
        {
            l[i] = r[i - 1] + 1;
            r[i] = min(i * block,n);
            sort(b[i].begin(),b[i].end());
        }
        for (ll i = 1; i <= n; i++)
        {
            ll opt,L,R,c;
            scanf("%lld%lld%lld%lld",&opt,&L,&R,&c);
            if (opt == 0)
                update(L,R,c);
            else
                printf("%lld
    ",query(L,R,c*c));
        }
    
        return 0;
    }
     
  • 相关阅读:
    EELS
    企业管理软件随想透视>包容,无形思想>有形方便
    定风波
    企业管理软件随想也谈企业框架软件需求
    Delphi数据库开发-前言
    游戏引发的……
    js 当前时间
    代码片段
    阶段总结
    Web界面设计
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8552705.html
Copyright © 2011-2022 走看看