Excellent data block structure 1- (v1.0)

--- --- restore content begins

v1.0, seek amendments Gangster

As we all know, Xinlong sister is a malignant tumor.

A data structure that often cancer.

It is the most out of the block.

Well, they nest today to learn excellent (violent) show (force) data structure - Block

Lovely Yoshino.

qaq

 

What is the part-one block?

Block, by definition, equal to the sequence into a plurality of blocks, for each block, maintenance information, and then combined.

part-two block principle, to achieve?

Now, we have a problem, for each of a sequence number, interval addition, seeking intervals and (assuming we do not is a thing called tree line)

Violence practices:

Modify violence, violence inquiry, apparently fly T, the time complexity of O (n²).

Consider optimizing violence:

Ω the sequence into blocks, each block maintains a TAG.

l, r-piece portion and the interval is divided into fragmented block portion.

For monolithic part, we add directly to the TAG block x.

For the scattered parts, we add violence.

Query is the same.

For the portion of the block, the block is the original and + (n / ω) * TAG>

For the scattered parts, direct violence inquiry.

time complexity.

Up ω a piece, so the time complexity of O (ω).

Fragmented by up to (n / ω) a time complexity O (n / ω).

Obviously ω = sqrt (n) is optimal.

Therefore, the time complexity of block m * sqrt (n).

Block probably realized:

Bel record array, which represents a point belonging to a block.

Recording lft, rgt array, the representative point of each block left and right points

Then each piece of information and statistics.

For each query

If the two endpoints in the same block, the violence inquiry.

Otherwise, the first piece of information queries, then scattered violence inquiry section

For each modification.

Direct hit single piece of information TAG, violence modify fragmented parts.

part three- example (may vary due to different time wrote the title may be quite different, code style)

1. Danfei sheep (luogu3203)

Title effect: Lostmonkey put on the ground along a line of n devices, each device sets the initial elastic coefficient ki, when sheep reaches an i-th unit, it will play the next step ki, ki + reach the i th device , if i + ki presence of a device, sheep Danfei. Sheep want to know when it is starting from the i-th unit, after a few shells will Danfei.

Basic problem of blocking means, each of the recording times can jump out of the current point located block, jump out after a few number of nodes.

代码:

#include <iostream>
#include <stdio.h> #include <string> #include <math.h> using namespace std; const int maxn=200005,maxm=505; int n,m,Q,num[maxn],bel[maxn],sum[maxn],outt[maxn]; struct block { int l,r; } a[maxn]; inline int read() { int x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar(); return x; } void doit(int l,int r) { for (int i=r; i>=l; i--) if (i+num[i]>a[bel[i]].r) sum[i]=1,outt[i]=i+num[i]; else sum[i]=sum[i+num[i]]+1,outt[i]=outt[i+num[i]]; } int main() { n=read(); m=sqrt(n); if (m*m<n) m++; int s=0; for (int i=1; i<=n; i++) num[i]=read(); for (int i=1; i<=n; i+=m) a[++s].l=i,a[s].r=i+m-1; if (s<m) a[++s].l=s*m+1,a[s].r=n; s=1; for (int i=1; i<=n; i++) { if (i>a[s].r) s++; bel[i]=s; } doit(1,n); Q=read(); while (Q--) { int x=read(),y=read()+1; if (x==1) { int ans=sum[y],x=outt[y]; for (int i=bel[y]; i<=m&&x<=n; i++) ans+=sum[x],x=outt[x]; printf("%d\n",ans); } else { int z=read(); num[y]=z; doit(a[bel[y]].l,a[bel[y]].r); } } return 0; }

 

2.lucky array(CF121E)

其实这题更简单,本该放在前面。

题目大意:区间加法,区间幸运数个数。

因为值域很小,我们发现在值域中的幸运数个数为30,所以我们先打个表,然后分块。

先统计每一个块内每一个数的出现次数,然后对于加法,我们还是打TAG,只不过在查询的时候要查询=(幸运数字-TAG)的个数

然后就好了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Rint register int
#define Temp template<typename T>
#define update(x,y,z) num[x][y]--,num[x][y+=z]++
using namespace std;
Temp inline void read(T &x) {
    x=0;T w=1,ch=getchar();
    while(!isdigit(ch)&&ch!='-') ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    x*=w;
} 
const int t[30]={4,7,44,47,74,77,444,447,474,477,744,747,774,777,4444,4447,4474,4477
,4744,4747,4774,4777,7444,7447,7474,7477,7744,7747,7774,7777};
const int m=317*5;
const int maxn=1e5+10;
int n,q,cnt;
int a[maxn];
int num[105][maxn],id[maxn],low[maxn],high[maxn],add[maxn];
int vis[10010];
int main() {
    read(n);read(q);
    for (int i=1;i<=n;++i) {
        read(a[i]);
        id[i]=i/m+1;
        num[id[i]][a[i]]++;
    }
    cnt=id[n];
    for (int i=1;i<=cnt;++i) {
        low[i]=(i-1)*m;
        high[i]=i*m-1;
    }
    low[1]=1;high[cnt]=n;
    for (int i=0;i<30;++i) vis[t[i]]=1;
    while(q--) {
        char kind[10];
        int l,r,d;
        scanf("%s%d%d",kind,&l,&r);
        int lx=id[l],rx=id[r];
        if(*kind=='a') {
            scanf("%d",&d);
            if(lx==rx) {
                for (int i=l;i<=r;++i) update(lx,a[i],d);
            }
            else {
                for (int i=l;i<=high[lx];++i) update(lx,a[i],d);
                for (int i=lx+1;i<rx;++i) add[i]+=d;
                for (int i=low[rx];i<=r;++i) update(rx,a[i],d);
            }
        }
        else {
            int ans=0;
            if(lx==rx) {
                for (int i=l;i<=r;++i) ans+=vis[a[i]+add[lx]];
            }
            else {
                for (int i=l;i<=high[lx];++i) ans+=vis[a[i]+add[lx]];
                for (int i=lx+1;i<rx;++i) {
                    for (int j=0;j<30;++j) if(add[i]<=t[j]) ans+=num[i][t[j]-add[i]];
                }
                for (int i=low[rx];i<=r;++i) ans+=vis[a[i]+add[rx]];
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

part four-Ynoi(不提供代码,不然没啥意思)

1.luogu5397 天降之物(第四分块)

题目大意:将所有x变成y,求最小的|i-j|使得a[i]==x && a[j]==y。

定义size[x]为x出现次数.

 

by lxl(写了一遍题解发现自己写得太垃圾了)

2. 五彩斑斓的世界。(第二分块)

题目大意:把区间>x的数减去x,求区间l,r内x的出现次数,值域1e5

解法:

提示了值域1e5,时间复杂度肯定与值域有关。

 

这题明显有一个性质,就是所有数的最大值总是单调不增的。

 

考虑利用这个性质

 

然后,他是要把l,r内>x的数-x,可一转化为把所有数-x,然后把<0的数+x

当最大值>=x*2时,把(1,x)合并到(x+1,x*2)

否则把(x+1,v)合并到(1,v-x)

这个用并查集维护即可。

所以神仙多多指教啊

 

 

---恢复内容结束---

Guess you like

Origin www.cnblogs.com/zjjandrew/p/11302466.html