分块
分块是啥? 暴力?
以前看分块看了一半,放在那里了,,今天想起来了,就又看了一下
分块的思想:把n分成根号n块然后暴力,
这也没啥,主要是记录一下
大段: 被分成的块 一大块
假设要维护的区间是 l~r 把在这个区间里的大段区间暴力维护一下,把两旁的不是一整段的小段暴力维护就好。
时间复杂度:根号n
例题:acwing 243
题目是 给出一个数组 两种操作:
Q l r 查询l~r的区间和
C l r x 把l~r区间里的数都加x
为什么不用线段树?树状数组?
因为我在学分块hhhhh
以下代码
代码:
代码下面有解析
粗心使人心态崩 ——我说的
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
typedef long long ll;
ll a[maxn];
ll sum[maxn];
ll add[maxn];
int nl[maxn];
int nr[maxn];
int vis[maxn];
void update(int l,int r,ll x)
{
int pl = vis[l];
int pr = vis[r];
if(pl == pr)
{
for (int i = l; i <= r; i ++ )
{
a[i] += x;
}
sum[pl] += x * (r - l + 1);
return;
}
for (int i = pl + 1; i < pr ; i ++ )
{
sum[i] += x * (nr[i] - nl[i] + 1);
add[i] += x;
}
for (int i = l; i <= nr[pl]; i ++ )
{
a[i] += x;
}
sum[pl] += (nr[pl] - l + 1) * x;
for (int i = nl[pr]; i <= r; i ++ )
{
a[i] += x;
}
sum[pr] += (r - nl[pr] + 1) * x;
}
ll query(int l,int r)
{
int pl = vis[l];
int pr = vis[r];
ll ans = 0;
if(pl == pr)
{
for (int i = l; i <= r; i ++ )
{
ans += a[i];
}
ans += add[pl]* (r- l + 1);
return ans;
}
for (int i = pl + 1; i < pr; i ++ )
{
ans += sum[i];
}
for (int i = l; i <= nr[pl]; i ++ )
{
ans += a[i];
}
ans += add[pl] * (nr[pl] - l + 1);
for (int i = nl[pr]; i <= r; i ++ )
{
ans +=a[i];
}
ans += add[pr]*(r - nl[pr] + 1);
return ans ;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n; i ++ )
{
scanf("%lld",&a[i]);
}
int t = sqrt(n);
for (int i = 1; i <= t; i ++ )
{
nl[i] = (i-1)*t+1;
nr[i] = i*t;
}
if(nr[t] != n)
{
nr[t+1] = n;
nl[t+1] = nr[t]+1;
t++;
}
for (int i = 1; i <= t; i++ )
{
for (int j = nl[i]; j <= nr[i]; j ++ )
{
vis[j] = i;
sum[i] += a[j];
}
}
while( m -- )
{
char t[2];
int l,r;
ll x;
scanf("%s",t);
if(t[0] == 'Q')
{
scanf("%d%d",&l,&r);
ll ans = query(l,r);
printf("%lld\n",ans);
}
else
{
scanf("%d%d%lld",&l,&r,&x);
update(l,r,x);
}
}
}
下面两边的意思是l~r区间里没有被完全包括的点
add:这个区间的增量,为什么要记录这个?直接加到sum里了呀? 这是我刚开始的问题,因为算两边的时候得把a[i]加上再加上add里的。add里记录的是这整个区间一起加的值修改两边的时候不用改add
a:原数组,修改的时候a数组里只修改两边的
sum:这个块里的和记得改两边得时候也要修改,
怎么感觉我表达的不清楚,好费劲,打扰了