• #数列分块入门 2


    这道题他们说不用分块就用平衡树,所以暴力拆解就用分块。

    做了两道分块已经渐渐明白分块的一些模板在这里就放一下吧(用vector比用数组md方便多了)

     1 void /*修改操作*//*查询操作*/ (int l,int r.....,int val)/*修改的要素*/
     2 {
     3     /*总是先修改(查询)角区间,就是那种不是整块整块的*/
     4     for(int i=l;i<=(id[l],n)/*注意结束的区间可能就是 l~r 所以取min*/;i++) 
     5     {
     6         /*暴力枚举修改(查询)*/
     7     } 
     8     if(/* l 和 r 不在同一个区间 就把 r 所在的角区间枚举修改(查询)*/)
     9     {
    10         /*暴力~*/
    11         /*但是能二分或者别的什么能搞出来,那肯定换一下啦*/
    12     }
    13     /*最后就整块整块的枚举啦*/ 
    14 } 

    这道题就是维护每个块内的元素成单调的,这样最后查询的时候就可以用二分(lower_bound)来进行查询会快很多,而剩下的就只有暴力、暴力再暴力。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 int block;
     5 int id[50009];
     6 int num[50009];
     7 int tag[10009];
     8 vector<int>v[10009];
     9 inline long long kd()
    10 {
    11     long long x=0,f=1;char ch=getchar();
    12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
    14     return x*f;
    15 }
    16 inline void reset(int now)
    17 {
    18     int r=min(id[now]*block,n);
    19     v[id[now]].clear();/*清空*/
    20     for(int i=(id[now]-1)*block+1;i<=r;i++)v[id[i]].push_back(num[i]);/*挼进去*/
    21     sort(v[id[now]].begin(),v[id[now]].end());/*排个序*/
    22 }
    23 inline void add(int l,int r,int c)
    24 {
    25     int minn=min(r,id[l]*block);
    26     for(int i=l;i<=minn;i++)num[i]+=c;/*暴力修改角区间*/
    27     reset(l);/*同下面reset的注释*/
    28     if(id[l]!=id[r])/*如果 l 和 r 不在个区间之内*/
    29     {
    30         for(int i=(id[r]-1)*block+1;i<=r;i++)num[i]+=c;/*同样暴力*/
    31         reset(r);/*角区间进行修改之后就打乱的顺序,所以重新排序*/
    32     }
    33     for(int i=id[l]+1;i<=id[r]-1;i++)tag[i]+=c;/*直接用tag来修改整块区间*/
    34 }
    35 int query(int l,int r,int c)
    36 {
    37     int ans=0;
    38     int minn=min(r,id[l]*block);
    39     for(int i=l;i<=minn;i++)
    40         if(num[i]+tag[id[i]]<c)ans++;/*暴力枚举角区间*/
    41     if(id[l]!=id[r])
    42     {
    43         for(int i=(id[r]-1)*block+1;i<=r;i++)
    44         {
    45             if(num[i]+tag[id[i]]<c)ans++;/*再次暴力枚举*/
    46         }
    47     }
    48     for(int i=id[l]+1;i<=id[r]-1;i++)
    49     {
    50         int x=c-tag[i];
    51         ans+=lower_bound(v[i].begin(),v[i].end(),x)-v[i].begin();/*整块的就直接二分查找*/
    52     }
    53     return ans;
    54 }
    55 int main()
    56 {
    57     n=kd();
    58     for(int i=1;i<=n;i++)num[i]=kd();
    59     block=(int)sqrt(n);
    60     for(int i=1;i<=n;i++)
    61     {
    62         id[i]=(i-1)/block+1;
    63         v[id[i]].push_back(num[i]);
    64     }
    65     for(int i=1;i<=id[n];i++)
    66         sort(v[i].begin(),v[i].end());
    67     for(int i=1;i<=n;i++)
    68     {
    69         int opt=kd();
    70         int l=kd(),r=kd(),c=kd();
    71         if(opt==0)add(l,r,c);
    72         if(opt==1)cout<<query(l,r,c*c)<<endl;
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    Android Studio 2.2.2导入Eclipse中创建的项目
    mvc上传到云虚拟机的问题解决
    基于矢量数据的逆地理编码功能实现
    离线地图解决方案(二):地图基本控制
    离线地图解决方案(一):加载瓦片地图
    离线地图解决方案
    openlayers应用“四”:百度地图纠偏续
    openlayers应用“三”:百度地图纠偏
    openlayers应用(二):加载百度离线瓦片
    openlayers3应用一:显示百度地图
  • 原文地址:https://www.cnblogs.com/1129-tangqiyuan/p/11779879.html
Copyright © 2020-2023  润新知