zoukankan      html  css  js  c++  java
  • LibreOJ 6278 数列分块入门 2(分块区间加法,二分)

    题目链接

    解题思路

      询问区间小于某个数个个数显然可以用二分来做,但是如果配合上区间加法就有些复杂了。即使对每个区间排序,用标记来代替修改,但是对于边缘的数据来说,需要暴力修改,而暴力修改后打破区间的有序性。那就暴力修改之后再重新排序(没错,就是这么狠(笑

    代码

    const int maxn = 1e5+10;
    struct INFO {
        int num, i;
        INFO(int a=0, int b=0): num(a), i(b) {}
        bool operator < (const INFO &a) const {
            return num < a.num;
        }
    } arr[maxn];
    int n,sz,num,l[maxn],r[maxn],bl[maxn],lazy[maxn];
    void build() {
        num = (n+sz-1)/sz;
        for (int i = 1; i<=num; ++i) {
            l[i] = (i-1)*sz+1, r[i] = i*sz;
        }
        r[num] = n;
        for (int i = 1; i<=n; ++i) bl[i] = (i-1)/sz+1;
        for (int i = 1; i<=num; ++i) sort(arr+l[i],arr+r[i]+1); 
    }
    void update(int a, int b, int c) {
        if (bl[a]==bl[b]) {
            for (int i = l[bl[a]]; i<=r[bl[a]]; ++i)    
                if (arr[i].i>=a && arr[i].i<=b) arr[i].num += c;
            sort(arr+l[bl[a]], arr+r[bl[a]]+1);
            return;
        }
        for (int i = bl[a]+1; i<bl[b]; ++i) lazy[i] += c;
        for (int i = l[bl[a]]; i<=r[bl[a]]; ++i) 
            if (arr[i].i>=a) arr[i].num += c;
        for (int i = l[bl[b]]; i<=r[bl[b]]; ++i) 
            if (arr[i].i<=b) arr[i].num += c;
        sort(arr+l[bl[a]], arr+r[bl[a]]+1);
        sort(arr+l[bl[b]], arr+r[bl[b]]+1);
    }
    int find(int a, int b, int c) {
        int ans = 0;
        if (bl[a]==bl[b]) {
            for (int i = l[bl[a]]; i<=r[bl[a]]; ++i) 
                if (arr[i].i>=a && arr[i].i<=b && arr[i].num+lazy[bl[i]]<c) ++ans;
            return ans;
        }
        for (int i = bl[a]+1; i<bl[b]; ++i)  
            ans += lower_bound(arr+l[i],arr+r[i]+1,INFO(c-lazy[i],0))-arr-l[i];
        for (int i = l[bl[a]]; i<=r[bl[a]]; ++i) 
            if (arr[i].i>=a && arr[i].num+lazy[bl[i]]<c) ++ans;
        for (int i = l[bl[b]]; i<=r[bl[b]]; ++i) 
            if (arr[i].i<=b && arr[i].num+lazy[bl[i]]<c) ++ans;
        return ans;
    }
    int main() {
        scanf("%d",&n);
        for (int i = 1; i<=n; ++i) {
            scanf("%d",&arr[i].num);
            arr[i].i = i;
        }
        sz = sqrt(n); build();
        for (int i = 1,op,l,r,c; i<=n; ++i) {
            scanf("%d%d%d%d",&op,&l,&r,&c);
            if (!op) update(l,r,c);
            else printf("%d
    ",find(l,r,c*c));
        }
        return 0;                                                                 
    }
    
  • 相关阅读:
    webapi支持session
    webapi返回数据同时支持xml与json
    webapi权限控制
    Asp.net 将js文件打包进dll 方法
    All Media to FLV asp.net在线视频自动转换并截图调试成功!
    未能从程序集“System.ServiceModel
    [javascript]浮动广告
    [python]multi thread tcp connect port scanner
    [vc]让你Y的用YY
    [python]扫描网站后台脚本
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13359014.html
Copyright © 2011-2022 走看看