zoukankan      html  css  js  c++  java
  • LOJ-6279-数列分块入门3(分块, 二分)

    链接:

    https://loj.ac/problem/6279

    题意:

    给出一个长为 的数列,以及 个操作,操作涉及区间加法,询问区间内小于某个值 的前驱(比其小的最大元素)。

    思路:

    同样的分块加二分,只不过是更新值

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    //#include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    #include <string>
    #include <assert.h>
    #include <iomanip>
    #define MINF 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5+10;
    
    int a[MAXN];
    int Rank[MAXN], Tag[MAXN];
    vector<int> Vec[MAXN];
    int part, n;
    
    void Re(int pos)
    {
        Vec[pos].clear();
        for (int i = (pos-1)*part+1;i <= pos*part;i++)
            Vec[pos].push_back(a[i]);
        sort(Vec[pos].begin(), Vec[pos].end());
    }
    
    void Update(int l, int r, int c)
    {
        for (int i = l;i <= min(Rank[l]*part, r);i++)
            a[i] += c;
        Re(Rank[l]);
        if (Rank[l] != Rank[r])
        {
            for (int i = max(l, (Rank[r]-1)*part+1);i <= r;i++)
                a[i] += c;
            Re(Rank[r]);
        }
        for (int i = Rank[l]+1;i <= Rank[r]-1;i++)
        {
            Tag[i] += c;
        }
    }
    
    int Query(int l, int r, int c)
    {
        int res = -1;
        for (int i = l;i <= min(Rank[l]*part, r);i++)
        {
            if (a[i]+Tag[Rank[l]] < c)
                res = max(res, a[i]+Tag[Rank[l]]);
        }
        if (Rank[l] != Rank[r])
        {
            for (int i = max((Rank[r]-1)*part+1, l);i <= r;i++)
            {
                if (a[i]+Tag[Rank[r]] < c)
                    res = max(res, a[i]+Tag[Rank[r]]);
            }
        }
        for (int i = Rank[l]+1;i <= Rank[r]-1;i++)
        {
            int pos = lower_bound(Vec[i].begin(), Vec[i].end(), c-Tag[i])-Vec[i].begin();
            if (pos >= 1)
                res = max(res, Vec[i][pos-1]+Tag[i]);
        }
        return res;
    }
    
    int main()
    {
    
        scanf("%d", &n);
        part = sqrt(n);
        for (int i = 1;i <= n;i++)
            scanf("%d", &a[i]);
        for (int i = 1;i <= n;i++)
        {
            Rank[i] = (i-1)/part+1;
            Vec[Rank[i]].push_back(a[i]);
        }
        for (int i = 1;i <= Rank[n];i++)
            sort(Vec[i].begin(), Vec[i].end());
        int op, l, r, c;
        for (int i = 1;i <= n;i++)
        {
            scanf("%d %d %d %d", &op, &l, &r, &c);
            if (op == 0)
                Update(l, r, c);
            else
                printf("%d
    ", Query(l, r, c));
        }
    
        return 0;
    }
    
  • 相关阅读:
    2013 新春快乐
    石头剪刀布游戏
    【MTK】MTK 报错集锦
    爱上双节棍男生的十五个理由
    Jni下NDK开发的bug问题汇总
    NDK中c语言logcat环境的搭建
    Android中Alertdialog对话框点击消失?
    Android上关于cmwap/cmnet网络切换的疑惑?
    Jni调用方法产生java.lang.UnsatisfiedLinkError错误
    android.os.NetworkOnMainThreadException问题
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11397561.html
Copyright © 2011-2022 走看看