• [LOJ6281]数列分块入门 5


    题目大意:
      给你一个长度为$n(nleq50000)$的序列$A(0leq A_i<2^{31})$,支持进行以下两种操作:
        1.将区间$[l,r]$中所有数开方;
        2.询问区间$[l,r]$的和。
    思路:
      分块。
      因为当一个区间内的所有$A_i$都$leq1$时,操作1对答案没有影响,因此我们可以记录每个区间是否还有操作的必要。如果还有大于$1$的数,就暴力进行操作,否则跳过。易证每个区间最多开方4次。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 typedef long long int64;
     6 inline int getint() {
     7     register char ch;
     8     register bool neg=false;
     9     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
    10     register int x=ch^'0';
    11     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    12     return neg?-x:x;
    13 }
    14 const int N=50001;
    15 int val[N],bel[N],begin[N],end[N],max[N];
    16 int64 sum[N];
    17 inline void modify(const int &l,const int &r,const int &c) {
    18     if(bel[l]==bel[r]) {
    19         for(register int i=l;i<=r;i++) val[i]=sqrt(val[i]);
    20         sum[bel[l]]=max[bel[l]]=0;
    21         for(register int i=begin[bel[l]];i<=end[bel[l]];i++) {
    22             sum[bel[l]]+=val[i];
    23             max[bel[l]]=std::max(max[bel[l]],val[i]);
    24         }
    25         return;
    26     }
    27     for(register int i=l;bel[i]==bel[l];i++) val[i]=sqrt(val[i]);
    28     for(register int i=r;bel[i]==bel[r];i--) val[i]=sqrt(val[i]);
    29     for(register int i=bel[l]+1;i<bel[r];i++) {
    30         if(max[i]==1) continue;
    31         for(register int j=begin[i];j<=end[i];j++) val[j]=sqrt(val[j]);
    32     }
    33     for(register int i=bel[l];i<=bel[r];i++) {
    34         if(max[i]==1) continue;
    35         sum[i]=max[i]=0;
    36         for(register int j=begin[i];j<=end[i];j++) {
    37             sum[i]+=val[j];
    38             max[i]=std::max(max[i],val[j]);
    39         }
    40     }
    41 }
    42 inline int64 query(const int &l,const int &r) {
    43     int64 ret=0;
    44     if(bel[l]==bel[r]) {
    45         for(register int i=l;i<=r;i++) ret+=val[i];
    46         return ret;
    47     }
    48     for(register int i=l;bel[i]==bel[l];i++) ret+=val[i];
    49     for(register int i=r;bel[i]==bel[r];i--) ret+=val[i];
    50     for(register int i=bel[l]+1;i<bel[r];i++) ret+=sum[i];
    51     return ret;
    52 }
    53 int main() {
    54     const int n=getint(),block=sqrt(n);
    55     for(register int i=1;i<=n;i++) {
    56         val[i]=getint();
    57         bel[i]=i/block;
    58         if(!begin[bel[i]]) begin[bel[i]]=i;
    59         end[bel[i]]=i;
    60         sum[bel[i]]+=val[i];
    61         max[bel[i]]=std::max(max[bel[i]],val[i]);
    62     }
    63     for(register int i=0;i<n;i++) {
    64         const int opt=getint(),l=getint(),r=getint(),c=getint();
    65         if(opt) {
    66             printf("%lld
    ",query(l,r));
    67         } else {
    68             modify(l,r,c);
    69         }
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    react中的生命周期钩子
    vue小知识
    vue发布中的前后端分离和前后端不分离
    vue中的vuex
    vue项目的发布
    stylus解决移动端1像素
    一行代码实现数组去重(ES6)
    详解js中Number()、parseInt()和parseFloat()的区别_javascript技巧
    关于element-ui 的日期时间选择器的超出时间无法选择的设置
    git使用
  • 原文地址:https://www.cnblogs.com/skylee03/p/8449496.html
Copyright © 2020-2023  润新知