zoukankan      html  css  js  c++  java
  • 【BZOJ 3343 】 分块

    3343: 教主的魔法

    Description

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

    Input

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

    Output

           对每个“A”询问输出一行,仅含一个整数,表示闭区间 [LR] 内身高大于等于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。
     
     
    【分析】
      这一次打这样的分块。
      这道题,n极大,q却很小。
      树套树对付这题连空间都承受不了。
      其他方法我也想不到了。
      看了黄学长的题解,觉得好有道理hh。。

    就是每一块的个数为根号n

    修改:

    对于一整块,直接打add标记

    头尾俩块不完整的进行暴力修改重构

    查询

    每一块内排序,在第i块内二分查找大等于C-add[i]的数字

    头尾俩块暴力查询

    转自:http://hzwer.com/2784.html

      整块的修改,直接在这一块上面大标记,(不用重新排序因为不改变相对大小的)

      总时间复杂度是q√n log(√n) = 3000*1000*10=3*10^7 

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 #define Maxn 1000010
     9 #define Mn 1010
    10 
    11 int a[Maxn],pos[Maxn],b[Maxn];
    12 int rt[Mn],ft[Mn],add[Mn];
    13 int sq;
    14 
    15 bool cmp(int x,int y) {return x>y;}
    16 
    17 void upd(int x)
    18 {
    19     for(int i=ft[x];i<=rt[x];i++) b[i]=a[i];
    20     sort(b+ft[x],b+1+rt[x],cmp);
    21 }
    22 
    23 void change(int x,int y,int c)
    24 {
    25     if(pos[x]==pos[y])
    26     {
    27         for(int i=x;i<=y;i++) a[i]+=c;
    28         upd(pos[x]);
    29     }
    30     else
    31     {
    32         for(int i=x;i<=rt[pos[x]];i++) a[i]+=c;
    33         for(int i=ft[pos[y]];i<=y;i++) a[i]+=c;
    34         for(int i=pos[x]+1;i<pos[y];i++) add[i]+=c;
    35         upd(pos[x]);upd(pos[y]);
    36     }
    37 }
    38 
    39 int ffind(int x,int y)
    40 {
    41     int l=ft[x],r=rt[x];
    42     if(b[l]+add[x]<y) return 0;
    43     while(l<r)
    44     {
    45         int mid=(l+r+1)>>1;
    46         if(b[mid]+add[x]>=y) l=mid;
    47         else r=mid-1;
    48     }
    49     return l-ft[x]+1;
    50 }
    51 
    52 int query(int x,int y,int c)
    53 {
    54     int ans=0;
    55     if(pos[x]==pos[y])
    56     {
    57         for(int i=x;i<=y;i++) if(a[i]+add[pos[i]]>=c) ans++;
    58     }
    59     else
    60     {
    61         for(int i=x;i<=rt[pos[x]];i++) if(a[i]+add[pos[x]]>=c) ans++;
    62         for(int i=ft[pos[y]];i<=y;i++) if(a[i]+add[pos[y]]>=c) ans++;
    63         for(int i=pos[x]+1;i<pos[y];i++) ans+=ffind(i,c);
    64     }
    65     return ans;
    66 }
    67 
    68 int main()
    69 {
    70     int n,q;
    71     scanf("%d%d",&n,&q);
    72     sq=(int)ceil(sqrt((double)n));
    73     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    74     for(int i=1;i<=n;i++) b[i]=a[i];
    75     for(int i=1;i<=n;i++) pos[i]=(i-1)/sq+1;
    76     for(int i=1;i<n;i++) if(pos[i]!=pos[i+1]) rt[pos[i]]=i,ft[pos[i+1]]=i+1;
    77     ft[1]=1;rt[pos[n]]=n;
    78     for(int i=1;i<=pos[n];i++) add[i]=0;
    79     for(int i=1;i<=pos[n];i++) sort(b+ft[i],b+rt[i]+1,cmp);
    80     for(int i=1;i<=q;i++)
    81     {
    82         char s[10];    
    83         int x,y,c;
    84         scanf("%s%d%d%d",s,&x,&y,&c);
    85         if(s[0]=='M')
    86         {
    87             change(x,y,c);
    88         }
    89         else
    90         {
    91             printf("%d
    ",query(x,y,c));
    92         }
    93     }
    94     return 0;
    95 }
    View Code

    2016-12-11 15:36:06

  • 相关阅读:
    eclipse如何与git 配合工作。
    git托管代码(二)
    PPC2003 安装 CFNET 3.5成功
    我的Window Mobile WCF 項目 第三篇 WM窗体设计
    我的Window Mobile WCF 項目 第一篇Mobile开发和WinForm开发的区别
    我的Window Mobile WCF 項目 第七天
    我的Window Mobile WCF 項目 第二篇 WindowsMobile访问WCF
    WCF 用vs2010 和 vs2008的简单对比测试
    vs2010beta1 和 搜狗输入法 冲突,按下 Ctrl 键就报错,重装搜狗解决
    我的Window Mobile WCF 項目 第六天 (二)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6159699.html
Copyright © 2011-2022 走看看