zoukankan      html  css  js  c++  java
  • [loj6278]数列分块入门2

    做法1

    以$K$为块大小分块,并对每一个块再维护一个排序后的结果,预处理复杂度为$o(nlog K )$

    区间修改时将整块打上标记,散块暴力修改并归并排序,单次复杂度为$o(frac{n}{K}+K)$

    区间查询时在整块中二分,散块暴力枚举,单次复杂度为$o(frac{n}{K}log K+K)$

    显然取块大小为$K=sqrt{nlog n}$时最优,单次复杂度均为$o(nsqrt{nlog n})$

    时间复杂度为$o(nlog n)-o(sqrt{nlog n})$

    做法2

    瓶颈显然在于整块的二分,考虑对其批量处理

    具体的,对于整块的询问先记录在该块上而不执行,在当一个块要被作为散块暴力修改时再处理之前记录的所有操作(标记可以先减去,注意到该块的序列在这次修改前不会变化)

    将这些询问基数排序(当底数较大时可以认为是线性的),再利用单调性进行查询,即做到了这样的查询均摊线性(注意$o(K)$的复杂度暴力修改本来就有),那么取$K=sqrt{n}$即可

    时间复杂度为$o(nlog n)-o(sqrt{n})$

    做法3

    实际上是在$frac{n}{K}$个长为$K$的序列中二分,那么即可使用类似[luogu6466]分散层叠算法的做法

    具体的,再选择一个阈值$B$,并将连续$B$个块称为一组,对每一组仅考虑每一个块中(排序后)下标是$B$的倍数的位置,即构成$B$个长度为$frac{K}{B}$的序列,对其使用做法4维护

    预处理的复杂度即为$o(frac{n}{BK}cdot K)=o(frac{n}{B})$(当然还有$o(nlog n)$的排序复杂度)

    区间修改时将整组和整块打上标记,散组和散块都暴力修改,单次复杂度为$o(frac{n}{K}+K)$

    区间查询时,将位置分为以下三类:

    1.对整组直接查询,至多$o(frac{n}{BK})$组,每组的复杂度为$o(Blog B+log BK)$(可以$o(B+log BK)$找到每一个块中第一个下标是$B$的倍数且大于等于$x^{2}$的数,再向前$B$个位置二分即可)

    2.对散组的整块二分查询,至多$o(B)$个块,每块的复杂度为$o(log K)$

    3.对散组的散块暴力查询,至多$o(K)$个位置,复杂度也为$o(K)$

    综上,单次复杂度为$o(K+frac{n}{K}log B+frac{n}{BK}log BK)$,显然取$K=sqrt{nlog log n},B=log n$最优

    时间复杂度为$o(nlog n)-o(sqrt{nloglog n})$

    做法4

    同样使用[luogu6466]分散层叠算法的做法,但考虑做法4沿用做法3的部分

    具体的,直接对$frac{n}{K}$个块建立一个分治结构(也即线段树),并且以$frac{1}{3}$的比例取元素(即合并时仅取下标是3的倍数的位置上的元素),此时序列长度和即为$o(n)$(当然取偶数位置也是$o(n)$的)

    区间修改时对整块打上标记(即线段树),并对散块暴力修改后重新维护,注意到一个叶子节点到根路径上的序列长度依次为$K,frac{2}{3}K,frac{4}{9}K,...$,那么总和即为$o(K)$,也即单次复杂度为$o(log frac{n}{K}+K)$

    区间查询时对整块直接在该结构上查询,只需要在根上二分一次并递归,注意到一共只有$o(frac{n}{K})$个节点,因此这部分的复杂度为$o(log K+frac{n}{K})$,散块暴力复杂度仍为$o(K)$

    综上,单次复杂度为$o(K+frac{n}{K})$,显然取$K=sqrt{n}$最优

    时间复杂度为$o(nlog n)-o(sqrt{n})$

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 50005
      4 #define K 300
      5 #define D 3
      6 #define ll long long
      7 #define L (k<<1)
      8 #define R (L+1)
      9 #define mid (l+r>>1)
     10 int n,k,p,l,r,x,ans,num[11],id[N],bl[N],st[K],ed[K],Pos[2],pos[K<<2][K][2];
     11 ll a[N],tag[K<<2],b[K<<2][K];
     12 int read(){
     13     int x=0,flag=0;
     14     char c=getchar();
     15     while ((c<'0')||(c>'9')){
     16         if (c=='-')flag=1;
     17         c=getchar();
     18     }
     19     while ((c>='0')&&(c<='9')){
     20         x=x*10+(c-'0');
     21         c=getchar();
     22     }
     23     if (flag)x=-x;
     24     return x;
     25 }
     26 void write(int x,char c=''){
     27     while (x){
     28         num[++num[0]]=x%10;
     29         x/=10;
     30     }
     31     if (!num[0])putchar('0');
     32     while (num[0])putchar(num[num[0]--]+'0');
     33     putchar(c);
     34 }
     35 bool cmp(int x,int y){
     36     return a[x]<a[y];
     37 }
     38 void upd(int k,int l,int r,int x){
     39     vector<int>v0,v1;
     40     for(int i=l;i<=r;i++)a[i]+=x;
     41     for(int i=st[k];i<=ed[k];i++)
     42         if ((l<=id[i])&&(id[i]<=r))v0.push_back(id[i]);
     43         else v1.push_back(id[i]);
     44     for(int i=st[k],x=0,y=0;i<=ed[k];i++){
     45         if ((x<v0.size())&&((y==v1.size())||(cmp(v0[x],v1[y]))))id[i]=v0[x++];
     46         else id[i]=v1[y++];
     47     }
     48 }
     49 void get(int k,int x){
     50     b[k][0]=0;
     51     for(int i=st[x];i<=ed[x];i++)b[k][++b[k][0]]=a[id[i]];
     52 }
     53 void up(int k){
     54     b[k][0]=0;
     55     int x=1,y=1;
     56     while ((x<=b[L][0])||(y<=b[R][0])){
     57         if ((x<=b[L][0])&&((y>b[R][0])||(b[L][x]+tag[L]<b[R][y]+tag[R]))){
     58             b[k][++b[k][0]]=b[L][x]+tag[L];
     59             pos[k][b[k][0]][0]=x;
     60             pos[k][b[k][0]][1]=0;
     61             x+=D;
     62         }
     63         else{
     64             b[k][++b[k][0]]=b[R][y]+tag[R];
     65             pos[k][b[k][0]][0]=0;
     66             pos[k][b[k][0]][1]=y;
     67             y+=D;
     68         }
     69     }
     70     memset(Pos,0,sizeof(Pos));
     71     for(int i=1;i<=b[k][0];i++)
     72         for(int p=0;p<2;p++){
     73             if (pos[k][i][p])Pos[p]=pos[k][i][p];
     74             pos[k][i][p]=Pos[p];
     75         }
     76 }
     77 void build(int k,int l,int r){
     78     if (l==r){
     79         get(k,l);
     80         return;
     81     }
     82     build(L,l,mid);
     83     build(R,mid+1,r);
     84     up(k);
     85 }
     86 void update_point(int k,int l,int r,int x){
     87     if (l==r){
     88         get(k,x);
     89         return;
     90     }
     91     if (x<=mid)update_point(L,l,mid,x);
     92     else update_point(R,mid+1,r,x);
     93     up(k);
     94 }
     95 void update_seg(int k,int l,int r,int x,int y,int z){
     96     if ((l>y)||(x>r))return;
     97     if ((x<=l)&&(r<=y)){
     98         tag[k]+=z;
     99         return;
    100     }
    101     update_seg(L,l,mid,x,y,z);
    102     update_seg(R,mid+1,r,x,y,z);
    103     up(k);
    104 }
    105 ll query_tag(int k,int l,int r,int x){
    106     if (l==r)return tag[k];
    107     if (x<=mid)return query_tag(L,l,mid,x)+tag[k];
    108     return query_tag(R,mid+1,r,x)+tag[k];
    109 }
    110 int query_seg(int k,int l,int r,int x,int y,int z,ll w){
    111     if ((l>y)||(x>r)||(!z))return 0;
    112     if (l==r)return z;
    113     int zl=pos[k][z][0],zr=pos[k][z][1];
    114     while ((zl<b[L][0])&&(b[L][zl+1]+tag[L]<w))zl++;
    115     while ((zr<b[R][0])&&(b[R][zr+1]+tag[R]<w))zr++;
    116     return query_seg(L,l,mid,x,y,zl,w-tag[L])+query_seg(R,mid+1,r,x,y,zr,w-tag[R]);
    117 }
    118 int query(int l,int r,ll x){
    119     int y=upper_bound(b[1]+1,b[1]+b[1][0]+1,x)-b[1]-1;
    120     return query_seg(1,1,bl[n],l,r,y,x);
    121 }
    122 int main(){
    123     n=read(),k=(int)sqrt(n);
    124     for(int i=1;i<=n;i++)a[i]=read();
    125     for(int i=1;i<=n;i++){
    126         id[i]=i;
    127         bl[i]=(i-1)/k+1;
    128         if (!st[bl[i]])st[bl[i]]=i;
    129         ed[bl[i]]=i;
    130     }
    131     for(int i=1;i<=bl[n];i++)sort(id+st[i],id+ed[i]+1,cmp);
    132     build(1,1,bl[n]);
    133     for(int i=1;i<=n;i++){
    134         p=read(),l=read(),r=read(),x=read();
    135         if (!p){
    136             if (bl[l]==bl[r]){
    137                 upd(bl[l],l,r,x);
    138                 update_point(1,1,bl[n],bl[l]);
    139             }
    140             else{
    141                 update_seg(1,1,bl[n],bl[l]+1,bl[r]-1,x);
    142                 upd(bl[l],l,ed[bl[l]],x);
    143                 update_point(1,1,bl[n],bl[l]);
    144                 upd(bl[r],st[bl[r]],r,x);
    145                 update_point(1,1,bl[n],bl[r]);
    146             }
    147         }
    148         else{
    149             ans=0;
    150             if (bl[l]==bl[r]){
    151                 ll z=(ll)x*x-query_tag(1,1,bl[n],bl[l]);
    152                 for(int j=l;j<=r;j++)
    153                     if (a[j]<z)ans++;
    154             }
    155             else{
    156                 ans=query(bl[l]+1,bl[r]-1,(ll)x*x);
    157                 ll z=(ll)x*x-query_tag(1,1,bl[n],bl[l]);
    158                 for(int j=l;j<=ed[bl[l]];j++)
    159                     if (a[j]<z)ans++;
    160                 z=(ll)x*x-query_tag(1,1,bl[n],bl[r]);
    161                 for(int j=st[bl[r]];j<=r;j++)
    162                     if (a[j]<z)ans++;
    163             }
    164             write(ans,'
    ');
    165         }
    166     }
    167     return 0;
    168 }
    View Code
  • 相关阅读:
    warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    Windows10+CLion+OpenCV4.5.2开发环境搭建
    Android解决部分机型WebView播放视频全屏按钮灰色无法点击、点击全屏白屏无法播放等问题
    MediaCodec.configure Picture Width(1080) or Height(2163) invalid, should N*2
    tesseract
    Caer -- a friendly API wrapper for OpenCV
    Integrating OpenCV python tool into one SKlearn MNIST example for supporting prediction
    Integrating Hub with one sklearn mnist example
    What is WSGI (Web Server Gateway Interface)?
    Hub --- 机器学习燃料(数据)的仓库
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15233495.html
Copyright © 2011-2022 走看看