zoukankan      html  css  js  c++  java
  • [bzoj]3343 教主的魔法

    【题目描述】

    教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。

    每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)

    CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。

    WD巨懒,于是他把这个回答的任务交给了你。

    【输入格式】

     第1行为两个整数N、Q。Q为问题数与教主的施法数总和。

     第2行有N个正整数,第i个数代表第i个英雄的身高。

     第3到第Q+2行每行有一个操作:

    (1)若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。

    (2)若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。

    【输出格式】

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

     【样例输入】

    5 3

    1 2 3 4 5

    A 1 5 4

    M 3 5 1

    A 1 5 4

    【样例输出】

    2

    3

    【数据范围】

    【输入输出样例说明】

    原先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

    第一次写分块算法。。。

    大部分借鉴(明明95%都抄的)了黄学长的代码:http://hzwer.com/2784.html

    关于分块查找这里有篇详细说明:

    http://www.cnblogs.com/youngforever/articles/3125590.html

    http://blog.csdn.net/jinxiaoqiang0608/article/details/7767668

    分为sqrt(n)块,block表示分块大小,pos[i]表示第i个数字在第几块,m表示总共分为几块

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int n,m,q,block;
     8 int a[1000001],b[1000001],pos[1000001],add[1000001];
     9 
    10 void reset(int x)
    11 {
    12     int l=(x-1)*block+1,r=min(x*block,n);
    13     for(int i=l;i<=r;i++)
    14         b[i]=a[i];
    15     sort(b+l,b+r+1);//对单个块内进行排序
    16 }
    17 
    18 int find(int x,int z)//单个块内二分查找
    19 {
    20     int l=(x-1)*block+1,r=min(x*block,n);
    21     int last=r;
    22     while(l<=r)
    23     {
    24         int mid=(l+r)>>1;
    25         if(b[mid]<z) l=mid+1;
    26         else r=mid-1;
    27     }
    28     return last-l+1;
    29 }
    30 
    31 void update(int x,int y,int z)
    32 {
    33     if(pos[x]==pos[y])//同个块则暴力修改
    34         for(int i=x;i<=y;i++) a[i]=a[i]+z;
    35     else//不同块修改左右两边的块
    36     {
    37         for(int i=x;i<=pos[x]*block;i++) a[i]=a[i]+z;
    38         for(int i=(pos[y]-1)*block+1;i<=y;i++) a[i]=a[i]+z;
    39     }
    40     reset(pos[x]);reset(pos[y]);
    41     for(int i=pos[x]+1;i<pos[y];i++)//其余块用add标记,表示增加了z
    42         add[i]+=z;
    43 }
    44 
    45 int query(int x,int y,int z)
    46 {
    47     int sum=0;
    48     if(pos[x]==pos[y])//单个块暴力查找
    49     {
    50         for(int i=x;i<=y;i++)
    51             if(a[i]+add[pos[i]]>=z) sum++;
    52     }
    53     else//多个块左右两边的块暴力查找
    54     {
    55         for(int i=x;i<=pos[x]*block;i++)
    56             if(a[i]+add[pos[i]]>=z) sum++;
    57         for(int i=(pos[y]-1)*block+1;i<=y;i++)
    58             if(a[i]+add[pos[i]]>=z) sum++;
    59     }
    60     for(int i=pos[x]+1;i<pos[y];i++)//其余块每个二分查找
    61         sum+=find(i,z-add[i]);
    62     return sum;
    63 }
    64 
    65 int main()
    66 {
    67     scanf("%d %d",&n,&q);
    68     block=(int)sqrt(n);//每个块的大小
    69     for(int i=1;i<=n;i++)
    70     {
    71         scanf("%d",&a[i]);
    72         pos[i]=(i-1)/block+1;
    73         b[i]=a[i];
    74     }
    75     if(n%block) m=n/block+1;//计算块的个数,如有多余则+1
    76     else m=n/block;
    77     for(int i=1;i<=m;i++) reset(i);//对每个块进行块内排序
    78     for(int i=1;i<=q;i++)
    79     {
    80         char ch;int x,y,z;
    81         scanf("
    %c %d %d %d",&ch,&x,&y,&z);
    82         if(ch=='M') update(x,y,z);
    83         else printf("%d
    ",query(x,y,z));
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    mysqldump 导出数据库为DBname的表名为Tname的表结构 导出数据库的所有表的表结构
    mysqldump 备份某张表 Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions,
    nfs missing codepage or helper program, or other error
    date 增加一个小时 减少一个小时
    mysqldump 备份单个数据库
    mysql删除账户
    怎么删除某个用户的所有帖子?
    mongodb删除重复数据
    ReSharper2018破解详细方法
    激活windows和office
  • 原文地址:https://www.cnblogs.com/InWILL/p/6021008.html
Copyright © 2011-2022 走看看