• [LOJ6278]数列分块入门 2


    题目大意:
      给你一个长度为$n(nleq 50000)$的序列$A$,支持进行以下两种操作:
        1.将区间$[l,r]$中所有数加上$c$;
        2.询问区间$[l,r]$中小于$c^2$的数的个数。
    思路:
      分块。
      对于整块的数据打标记,零散的数据直接修改。同时维护同一块中从小到大的顺序,统计时对于同一块中的数二分答案,零散的数直接统计。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 #include<functional>
     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],s[N],tag[N],bel[N],begin[N],end[N];
    16 inline bool cmp(const int &a,const int &b) {
    17     return val[a]+tag[bel[a]]<val[b]+tag[bel[b]];
    18 }
    19 inline void modify(const int &l,const int &r,const int &c) {
    20     if(bel[l]==bel[r]) {
    21         for(register int i=l;i<=r;i++) val[i]+=c;
    22         std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+1,cmp);
    23         return;
    24     }
    25     for(register int i=l;bel[i]==bel[l];i++) val[i]+=c;
    26     std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+1,cmp);
    27     for(register int i=r;bel[i]==bel[r];i--) val[i]+=c;
    28     std::sort(&s[begin[bel[r]]],&s[end[bel[r]]]+1,cmp);
    29     for(register int i=bel[l]+1;i<bel[r];i++) tag[i]+=c;
    30 }
    31 inline int query(const int &l,const int &r,const int &c) {
    32     int ret=0;
    33     val[0]=c*c;
    34     if(bel[l]==bel[r]) {
    35         for(register int i=l;i<=r;i++) {
    36             if(val[i]+tag[bel[i]]<val[0]) ret++;
    37         }
    38         return ret;
    39     }
    40     for(register int i=l;bel[i]==bel[l];i++) {
    41         if(val[i]+tag[bel[i]]<val[0]) ret++;
    42     }
    43     for(register int i=r;bel[i]==bel[r];i--) {
    44         if(val[i]+tag[bel[i]]<val[0]) ret++;
    45     }
    46     for(register int i=bel[l]+1;i<bel[r];i++) {
    47         ret+=std::lower_bound(&s[begin[i]],&s[end[i]]+1,0,cmp)-&s[begin[i]];
    48     }
    49     return ret;
    50 }
    51 int main() {
    52     const int n=getint(),block=sqrt(n);
    53     for(register int i=1;i<=n;i++) {
    54         val[i]=getint();
    55         bel[i]=i/block;
    56         s[i]=i;
    57         if(!begin[bel[i]]) begin[bel[i]]=i;
    58         end[bel[i]]=i;
    59     }
    60     for(register int i=0;i<=bel[n];i++) {
    61         std::sort(&s[begin[i]],&s[end[i]]+1,cmp);
    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("%d
    ",query(l,r,c));
    67         } else {
    68             modify(l,r,c);
    69         }
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    ld: cannot find lXXX" 如lpthread lgomp
    Glib交叉编译:g__cancellable_lock undeclared!&HEADER/C_IN undeclared!&undefined reference to "localeconv"
    Android_清除/更新Bundle中的数据(不finish() Activity的情况下)
    读Kernel感悟Linux内核启动从hello world说起
    细数二十世纪最伟大的十大算法
    error: *** No iconv() implementation found in C library & libiconv 交叉编译 失败编译
    gnulib+glib+glibc+libc的不同转
    [Android] 以singleInstance模式加载的Activity怎么接收以Bundle方式传递过来的参数 By onNewIntent() but not onResum
    Glib在armlinux下的交叉编译
    python 笔记
  • 原文地址:https://www.cnblogs.com/skylee03/p/8445567.html
Copyright © 2020-2023  润新知