zoukankan      html  css  js  c++  java
  • 数据结构:分块-区间加法和询问小于指定元素的个数

    本题的分块儿需要提前预处理,预处理的时候就是把每块儿内元素排序,这样在查询的时候就可以二分查找了,从而减少了查询的效率

    当然对于块儿外元素还是暴力查找,最大查找2m次也就是2√n次

    区间加法还是同样适用一个修改标记,但是对于首尾的不完整块儿在修改之后这两块儿可能会出现乱序的情况

    重新排序一下就好了

    在有了加法标记的时候,查询时要考虑标记

    块内用(x – 加法标记)作为二分的值进行查找就可以了

    这个应该挺好理解的

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<vector>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=50005;
     7 int n,blo;
     8 int v[maxn],bl[maxn],atag[maxn];
     9 vector<int> ve[505];
    10 inline long long read()
    11 {
    12     long long x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 void reset(int x)
    18 {
    19     ve[x].clear();
    20     for(int i=(x-1)*blo+1;i<=min(x*blo,n);i++)
    21         ve[x].push_back(v[i]);
    22     sort(ve[x].begin(),ve[x].end());
    23 }
    24 void add(int a,int b,int c)
    25 {
    26     for(int i=a;i<=min(bl[a]*blo,b);i++) v[i]+=c;
    27     reset(bl[a]);
    28     if(bl[a]!=bl[b])
    29     {
    30         for(int i=(bl[b]-1)*blo+1;i<=b;i++) v[i]+=c;
    31         reset(bl[b]);
    32     }
    33     for(int i=bl[a]+1;i<=bl[b]-1;i++) atag[i]+=c;
    34 }
    35 int query(int a,int b,int c)
    36 {
    37     int ans=0;
    38     for(int i=a;i<=min(bl[a]*blo,b);i++)
    39         if(v[i]+atag[bl[a]]<c) ans++;
    40     if(bl[a]!=bl[b])
    41         for(int i=(bl[b]-1)*blo+1;i<=b;i++)
    42             if(v[i]+atag[bl[b]]<c) ans++;
    43     for(int i=bl[a]+1;i<=bl[b]-1;i++)
    44     {
    45         int x=c-atag[i];
    46         ans+=lower_bound(ve[i].begin(),ve[i].end(),x)-ve[i].begin();
    47     }
    48     return ans;
    49 }
    50 int main()
    51 {
    52     n=read();blo=sqrt(n);
    53     for(int i=1;i<=n;i++) v[i]=read();
    54     for(int i=1;i<=n;i++)
    55     {
    56         bl[i]=(i-1)/blo+1;
    57         ve[bl[i]].push_back(v[i]);
    58     }
    59     for(int i=1;i<=bl[n];i++)
    60         sort(ve[i].begin(),ve[i].end());
    61     for(int i=1;i<=n;i++)
    62     {
    63         int f=read(),a=read(),b=read(),c=read();
    64         if(f==0) add(a,b,c);
    65         if(f==1) printf("%d
    ",query(a,b,c*c));
    66     }
    67 }
  • 相关阅读:
    Leetcode 1191 K次串联后的最大子数组之和 Kadane 算法
    剑指Offer 38 字符串的排列
    explain结果每个字段的含义说明
    Timsort算法
    synchorized的锁升级
    进程IPC通信方式7种
    死锁知识点总结
    java中各种锁介绍
    运算符优先级记录
    C++ auto关键字
  • 原文地址:https://www.cnblogs.com/aininot260/p/9525314.html
Copyright © 2011-2022 走看看