zoukankan      html  css  js  c++  java
  • 【BZOJ】3343: 教主的魔法

    Description

    教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N
    每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤LRN)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第LR)个英雄的身高)
    CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。
    WD巨懒,于是他把这个回答的任务交给了你。
     

    Input

           第1行为两个整数NQQ为问题数与教主的施法数总和。
           第2行有N个正整数,第i个数代表第i个英雄的身高。
           第3到第Q+2行每行有一个操作:
    (1)       若第一个字母为“M”,则紧接着有三个数字LRW。表示对闭区间 [L, R] 内所有英雄的身高加上W
    (2)       若第一个字母为“A”,则紧接着有三个数字LRC。询问闭区间 [L, R] 内有多少英雄的身高大于等于C
     

    Output

           对每个“A”询问输出一行,仅含一个整数,表示闭区间 [L, R] 内身高大于等于C的英雄数。
     

    Sample Input

    5 3
    1 2 3 4 5
    A 1 5 4
    M 3 5 1
    A 1 5 4

    Sample Output

    2
    3

    HINT

    【输入输出样例说明】
    原先5个英雄身高为1、2、3、4、5,此时[1, 5]间有2个英雄的身高大于等于4。教主施法后变为1、2、4、5、6,此时[1, 5]间有3个英雄的身高大于等于4。
     
    【数据范围】
    对30%的数据,N≤1000,Q≤1000。
    对100%的数据,N≤1000000,Q≤3000,1≤W≤1000,1≤C≤1,000,000,000。
    题目大意:
      给定一个数列,修改和查询两种操作,修改每次给定一个区间,区间的所有元素都加上一个给定值,查询询问一段区间的数权值大于等于给定值的数有多少个。
    题解:
      分块。
      保证每块是排好序的,查找整块直接二分查找,然后散块暴力修改。
      add标记,这样排好序之后查找的话就可以通过二分跳跃很大一部分查找
      (整块增加的话区间相对大小不变。)
      注意+1和-1什么的说
      英文注释打得就像百度翻译一样……
     
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int MAXN = 1000001;
    int pos[MAXN], a[MAXN], b[MAXN], add[MAXN];
    int n, m ,block;
    void reset(int x)
    {
        int i;
        int l = (x-1) * block + 1;
        int r = x * block;
        if (r > n) r = n;
        for (i = l; i <= r; i++)
        {
            b[i] = a[i];
        }
        sort(b + l, b + r + 1);
    }
    int find(int x, int tar)
    {
        int l = (x - 1)*block + 1;
        int r = x*block;
        if (r > n) r = n;
        int mid, ret=r;
        while (l <= r)
        {
            mid = (l + r) >> 1;
            if (b[mid] >= tar) r = mid-1;
            else l = mid + 1;
        }
        return ret - l + 1;
    }
    void Modify(int L, int R, int tar)
    {
        int i;
        if (pos[L] == pos[R]) //L ans R are in the same block
        {
            for (i = L; i <= R; i++)
            {
                a[i] += tar;
            }
        }
        else 
        {
            for (i = L; i <= pos[L] * block; i++)
                a[i] += tar;
            for (i = (pos[R ]-1) * block +1; i <= R; i++)
                a[i] += tar;
        }
        reset(pos[L]);
        reset(pos[R]);
        for (i = pos[L] + 1; i < pos[R]; i++)
            add[i] += tar;
    }
    int Query(int L, int R, int tar)
    {
        int d = 0, i;
        if (pos[L] == pos[R])
        {
            for (i = L; i <= R; i++)
            {
                if (add[i] + a[i] >= tar)
                    d++;
            }
        }
        else
        {
            for (i = L; i <= pos[L] * block; i++)
                if (a[i] + add[pos[i]] >= tar) 
                    d++;
            for (i = (pos[R]-1) * block + 1; i <= R; i++)
                if (a[i] + add[pos[i]] >= tar) 
                    d++;
        }
        for (i = pos[L] + 1; i < pos[R]; i++)
            d += find(i, tar-add[i]);
        return d;
    }
    int main(int argc, char *argv[])
    {
        int i, j, x, y, z, T;
        char op;
        scanf("%d%d", &n, &T);
        block = (int)sqrt(n);
        for (i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            b[i] = i;
            pos[i] = (i - 1) / block + 1;
        }
        if (n%block)
            m = n / block + 1;
        else m = n / block;
        for (i = 1; i <= m; i++)
            reset(i);
        while (T--)
        {
            scanf("
    %c%d%d%d", &op, &x, &y, &z);
            if (op == 'M') Modify(x, y, z);
            else printf("%d
    ", Query(x, y, z));
        }
        return 0;
    }
  • 相关阅读:
    [WP]XCTF-Reversing-Newbie_calculations
    [WP]BUUCTF-Reverse-基础题(1-12)
    [WP]XCTF-notsequence
    [WP]XCTF-easyre-153
    [WP]XCTF- 攻防世界-crypto-新手练习区
    [WP]XCTF-simple-check-100
    [WP]XCTF-SignIn
    [WP]XCTF-666
    [WP]XCTF-Reversing-x64Elf-100
    [WP]XCTF-流浪者
  • 原文地址:https://www.cnblogs.com/BeyondW/p/5908139.html
Copyright © 2011-2022 走看看