1 数列分块入门_「分块」数列分块入门1 – 9 by hzwer

由于 CH 回档导致原题面丢失,感谢诸暨海亮高级中学帮助重写了题面

已上传至 LOJ

由于每道题题面太长,限于篇幅,只给出大意,具体题目见小组内赛题,代码附在文末

可能涉及的几个词语解释:

区间:数列中连续一段的元素

区间操作:将某个区间[a,b]的所有元素进行某种改动的操作

块:我们将数列划分成若干个不相交的区间,每个区间称为一个块

整块:在一个区间操作时,完整包含于区间的块

不完整的块:在一个区间操作时,只有部分包含于区间的块,即区间左右端点所在的两个块

分块入门 1 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值。

这是一道能用许多数据结构优化的经典题,可以用于不同数据结构训练。

数列分块就是把数列中每m个元素打包起来,达到优化算法的目的。

以此题为例,如果我们把每m个元素分为一块,共有n/m块,每次区间加的操作会涉及O(n/m)个整块,以及区间两侧两个不完整的块中至多2m个元素。

我们给每个块设置一个加法标记(就是记录这个块中元素一起加了多少),每次操作对每个整块直接O(1)标记,而不完整的块由于元素比较少,暴力修改元素的值。

每次询问时返回元素的值加上其所在块的加法标记。

这样每次操作的复杂度是O(n/m)+O(m),根据均值不等式,当m取√n时总复杂度最低,为了方便,我们都默认下文的分块大小为√n。

分块入门 2 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的元素个数。

有了上一题的经验,我们可以发现,数列简单分块问题实际上有三项东西要我们思考:

对于每次区间操作:

1.不完整的块的O(√n)个元素怎么处理?

2.O(√n)个 整块怎么处理?

3.要预处理什么信息(复杂度不能超过后面的操作)?

我们先来思考只有询问操作的情况,不完整的块枚举统计即可;而要在每个整块内寻找小于一个值的元素数,于是我们不得不要求块内元素是有序的,这样就能使用二分法对块内查询,需要预处理时每块做一遍排序,复杂度O(nlogn),每次查询在√n个块内二分,以及暴力2√n个元素,总复杂度O(nlogn + n√nlog√n)。

可以通过均值不等式计算出更优的分块大小,就不展开讨论了

那么区间加怎么办呢?

套用第一题的方法,维护一个加法标记,略有区别的地方在于,不完整的块修改后可能会使得该块内数字乱序,所以头尾两个不完整块需要重新排序,复杂度分析略。

在加法标记下的询问操作,块外还是暴力,查询小于(x – 加法标记)的元素个数,块内用(x – 加法标记)作为二分的值即可。

分块入门 3 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的前驱(比其小的最大元素)。

n<=100000其实是为了区分暴力和一些常数较大的写法。

接着第二题的解法,其实只要把块内查询的二分稍作修改即可。

不过这题其实想表达:可以在块内维护其它结构使其更具有拓展性,比如放一个 set,这样如果还有插入、删除元素的操作,会更加的方便。

分块的调试检测技巧:

可以生成一些大数据,然后用两份分块大小不同的代码来对拍,还可以根据运行时间尝试调整分块大小,减小常数。

分块入门 4 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间加法,区间求和。

这题的询问变成了区间上的询问,不完整的块还是暴力;而要想快速统计完整块的答案,需要维护每个块的元素和,先要预处理一下。

考虑区间修改操作,不完整的块直接改,顺便更新块的元素和;完整的块类似之前标记的做法,直接根据块的元素和所加的值计算元素和的增量。

分块入门 5 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间开方,区间求和。

稍作思考可以发现,开方操作比较棘手,主要是对于整块开方时,必须要知道每一个元素,才能知道他们开方后的和,也就是说,难以快速对一个块信息进行更新。

看来我们要另辟蹊径。不难发现,这题的修改就只有下取整开方,而一个数经过几次开方之后,它的值就会变成 0 或者 1。

如果每次区间开方只不涉及完整的块,意味着不超过2√n个元素,直接暴力即可。

如果涉及了一些完整的块,这些块经过几次操作以后就会都变成 0 / 1,于是我们采取一种分块优化的暴力做法,只要每个整块暴力开方后,记录一下元素是否都变成了 0 / 1,区间修改时跳过那些全为 0 / 1 的块即可。

这样每个元素至多被开方不超过4次,显然复杂度没有问题。

分块入门 6 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及单点插入,单点询问,数据随机生成。

先说随机数据的情况

之前提到过,如果我们块内用数组以外的数据结构,能够支持其它不一样的操作,比如此题每块内可以放一个动态的数组,每次插入时先找到位置所在的块,再暴力插入,把块内的其它元素直接向后移动一位,当然用链表也是可以的。

查询的时候类似,复杂度分析略。

但是这样做有个问题,如果数据不随机怎么办?

如果先在一个块有大量单点插入,这个块的大小会大大超过√n,那块内的暴力就没有复杂度保证了。

还需要引入一个操作:重新分块(重构)

每根号n次插入后,重新把数列平均分一下块,重构需要的复杂度为O(n),重构的次数为√n,所以重构的复杂度没有问题,而且保证了每个块的大小相对均衡。

当然,也可以当某个块过大时重构,或者只把这个块分成两半。

分块入门 7 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间乘法,区间加法,单点询问。

很显然,如果只有区间乘法,和分块入门 1 的做法没有本质区别,但要思考如何同时维护两种标记。

我们让乘法标记的优先级高于加法(如果反过来的话,新的加法标记无法处理)

若当前的一个块乘以m1后加上a1,这时进行一个乘m2的操作,则原来的标记变成m1*m2,a1*m2

若当前的一个块乘以m1后加上a1,这时进行一个加a2的操作,则原来的标记变成m1,a1+a2

分块入门 8 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c。

区间修改没有什么难度,这题难在区间查询比较奇怪,因为权值种类比较多,似乎没有什么好的维护方法。

模拟一些数据可以发现,询问后一整段都会被修改,几次询问后数列可能只剩下几段不同的区间了。

我们思考这样一个暴力,还是分块,维护每个分块是否只有一种权值,区间操作的时候,对于同权值的一个块就O(1)统计答案,否则暴力统计答案,并修改标记,不完整的块也暴力。

这样看似最差情况每次都会耗费O(n)的时间,但其实可以这样分析:

假设初始序列都是同一个值,那么查询是O(√n),如果这时进行一个区间操作,它最多破坏首尾2个块的标记,所以只能使后面的询问至多多2个块的暴力时间,所以均摊每次操作复杂度还是O(√n)。

换句话说,要想让一个操作耗费O(n)的时间,要先花费√n个操作对数列进行修改。

初始序列不同值,经过类似分析后,就可以放心的暴力啦。

分块入门 9 by hzwer

给出一个长为n的数列,以及n个操作,操作涉及询问区间的最小众数。

这是一道经典难题,其实可以支持修改操作,具体见陈立杰大神的区间众数解题报告。

而且不强制在线的话有很多做法,可以看我blog一道类似题目 czy的后宫3

bzoj2724 是道强制在线区间众数,而且题目背景写的不错,这道题的题解就贴传送门咯

程序

分块入门1:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int v[50005],bl[50005],atag[50005];

void add(int a,int b,int c)

{

for(int i=a;i<=min(bl[a]*blo,b);i++)

v[i]+=c;

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

v[i]+=c;

for(int i=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

int main()

{

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)printf("%d\n",v[b]+atag[bl[b]]);

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intv[50005],bl[50005],atag[50005];

voidadd(inta,intb,intc)

{

for(inti=a;i<=min(bl[a]*blo,b);i++)

v[i]+=c;

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

v[i]+=c;

for(inti=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

intmain()

{

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)printf("%d\n",v[b]+atag[bl[b]]);

}

return0;

}

分块入门2:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int v[50005],bl[50005],atag[50005];

vectorve[505];

void reset(int x)

{

ve[x].clear();

for(int i=(x-1)*blo+1;i<=min(x*blo,n);i++)

ve[x].push_back(v[i]);

sort(ve[x].begin(),ve[x].end());

}

void add(int a,int b,int c)

{

for(int i=a;i<=min(bl[a]*blo,b);i++)

v[i]+=c;

reset(bl[a]);

if(bl[a]!=bl[b])

{

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

v[i]+=c;

reset(bl[b]);

}

for(int i=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

int query(int a,int b,int c)

{

int ans=0;

for(int i=a;i<=min(bl[a]*blo,b);i++)

if(v[i]+atag[bl[a]]

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

if(v[i]+atag[bl[b]]

for(int i=bl[a]+1;i<=bl[b]-1;i++)

{

int x=c-atag[i];

ans+=lower_bound(ve[i].begin(),ve[i].end(),x)-ve[i].begin();

}

return ans;

}

int main()

{

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

ve[bl[i]].push_back(v[i]);

}

for(int i=1;i<=bl[n];i++)

sort(ve[i].begin(),ve[i].end());

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)printf("%d\n",query(a,b,c*c));

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intv[50005],bl[50005],atag[50005];

vectorve[505];

voidreset(intx)

{

ve[x].clear();

for(inti=(x-1)*blo+1;i<=min(x*blo,n);i++)

ve[x].push_back(v[i]);

sort(ve[x].begin(),ve[x].end());

}

voidadd(inta,intb,intc)

{

for(inti=a;i<=min(bl[a]*blo,b);i++)

v[i]+=c;

reset(bl[a]);

if(bl[a]!=bl[b])

{

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

v[i]+=c;

reset(bl[b]);

}

for(inti=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

intquery(inta,intb,intc)

{

intans=0;

for(inti=a;i<=min(bl[a]*blo,b);i++)

if(v[i]+atag[bl[a]]

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

if(v[i]+atag[bl[b]]

for(inti=bl[a]+1;i<=bl[b]-1;i++)

{

intx=c-atag[i];

ans+=lower_bound(ve[i].begin(),ve[i].end(),x)-ve[i].begin();

}

returnans;

}

intmain()

{

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

ve[bl[i]].push_back(v[i]);

}

for(inti=1;i<=bl[n];i++)

sort(ve[i].begin(),ve[i].end());

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)printf("%d\n",query(a,b,c*c));

}

return0;

}

分块入门3:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int v[100005],bl[100005],atag[100005];

setst[105];

void add(int a,int b,int c)

{

for(int i=a;i<=min(bl[a]*blo,b);i++)

{

st[bl[a]].erase(v[i]);

v[i]+=c;

st[bl[a]].insert(v[i]);

}

if(bl[a]!=bl[b])

{

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

{

st[bl[b]].erase(v[i]);

v[i]+=c;

st[bl[b]].insert(v[i]);

}

}

for(int i=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

int query(int a,int b,int c)

{

int ans=-1;

for(int i=a;i<=min(bl[a]*blo,b);i++)

{

int val=v[i]+atag[bl[a]];

if(val

}

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

{

int val=v[i]+atag[bl[b]];

if(val

}

for(int i=bl[a]+1;i<=bl[b]-1;i++)

{

int x=c-atag[i];

set::iterator it=st[i].lower_bound(x);

if(it==st[i].begin())continue;

--it;

ans=max(ans,*it+atag[i]);

}

return ans;

}

int main()

{

n=read();blo=1000;

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

st[bl[i]].insert(v[i]);

}

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)printf("%d\n",query(a,b,c));

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intv[100005],bl[100005],atag[100005];

setst[105];

voidadd(inta,intb,intc)

{

for(inti=a;i<=min(bl[a]*blo,b);i++)

{

st[bl[a]].erase(v[i]);

v[i]+=c;

st[bl[a]].insert(v[i]);

}

if(bl[a]!=bl[b])

{

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

{

st[bl[b]].erase(v[i]);

v[i]+=c;

st[bl[b]].insert(v[i]);

}

}

for(inti=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

intquery(inta,intb,intc)

{

intans=-1;

for(inti=a;i<=min(bl[a]*blo,b);i++)

{

intval=v[i]+atag[bl[a]];

if(val

}

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

{

intval=v[i]+atag[bl[b]];

if(val

}

for(inti=bl[a]+1;i<=bl[b]-1;i++)

{

intx=c-atag[i];

set::iteratorit=st[i].lower_bound(x);

if(it==st[i].begin())continue;

--it;

ans=max(ans,*it+atag[i]);

}

returnans;

}

intmain()

{

n=read();blo=1000;

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

st[bl[i]].insert(v[i]);

}

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)printf("%d\n",query(a,b,c));

}

return0;

}

分块入门4:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int bl[50005];

ll v[50005],atag[50005],sum[50005];

void add(int a,int b,int c)

{

for(int i=a;i<=min(bl[a]*blo,b);i++)

v[i]+=c,sum[bl[a]]+=c;;

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

v[i]+=c,sum[bl[b]]+=c;

for(int i=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

ll query(int a,int b)

{

ll ans=0;

for(int i=a;i<=min(bl[a]*blo,b);i++)

ans+=v[i]+atag[bl[a]];

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

ans+=v[i]+atag[bl[b]];

for(int i=bl[a]+1;i<=bl[b]-1;i++)

ans+=sum[i]+blo*atag[i];

return ans;

}

int main()

{

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

sum[bl[i]]+=v[i];

}

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)

printf("%d\n",query(a,b)%(c+1));

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intbl[50005];

llv[50005],atag[50005],sum[50005];

voidadd(inta,intb,intc)

{

for(inti=a;i<=min(bl[a]*blo,b);i++)

v[i]+=c,sum[bl[a]]+=c;;

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

v[i]+=c,sum[bl[b]]+=c;

for(inti=bl[a]+1;i<=bl[b]-1;i++)

atag[i]+=c;

}

llquery(inta,intb)

{

llans=0;

for(inti=a;i<=min(bl[a]*blo,b);i++)

ans+=v[i]+atag[bl[a]];

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

ans+=v[i]+atag[bl[b]];

for(inti=bl[a]+1;i<=bl[b]-1;i++)

ans+=sum[i]+blo*atag[i];

returnans;

}

intmain()

{

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

sum[bl[i]]+=v[i];

}

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)

printf("%d\n",query(a,b)%(c+1));

}

return0;

}

分块入门5:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int bl[50005];

int v[50005],sum[50005],flag[50005];

void solve_sqrt(int x)

{

if(flag[x])return;

flag[x]=1;

sum[x]=0;

for(int i=(x-1)*blo+1;i<=x*blo;i++)

{

v[i]=sqrt(v[i]),sum[x]+=v[i];

if(v[i]>1)flag[x]=0;

}

}

void add(int a,int b,int c)

{

for(int i=a;i<=min(bl[a]*blo,b);i++)

{

sum[bl[a]]-=v[i];

v[i]=sqrt(v[i]);

sum[bl[a]]+=v[i];

}

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

{

sum[bl[b]]-=v[i];

v[i]=sqrt(v[i]);

sum[bl[b]]+=v[i];

}

for(int i=bl[a]+1;i<=bl[b]-1;i++)

solve_sqrt(i);

}

int query(int a,int b)

{

int ans=0;

for(int i=a;i<=min(bl[a]*blo,b);i++)

ans+=v[i];

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

ans+=v[i];

for(int i=bl[a]+1;i<=bl[b]-1;i++)

ans+=sum[i];

return ans;

}

int main()

{

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

sum[bl[i]]+=v[i];

}

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)

printf("%d\n",query(a,b));

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intbl[50005];

intv[50005],sum[50005],flag[50005];

voidsolve_sqrt(intx)

{

if(flag[x])return;

flag[x]=1;

sum[x]=0;

for(inti=(x-1)*blo+1;i<=x*blo;i++)

{

v[i]=sqrt(v[i]),sum[x]+=v[i];

if(v[i]>1)flag[x]=0;

}

}

voidadd(inta,intb,intc)

{

for(inti=a;i<=min(bl[a]*blo,b);i++)

{

sum[bl[a]]-=v[i];

v[i]=sqrt(v[i]);

sum[bl[a]]+=v[i];

}

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

{

sum[bl[b]]-=v[i];

v[i]=sqrt(v[i]);

sum[bl[b]]+=v[i];

}

for(inti=bl[a]+1;i<=bl[b]-1;i++)

solve_sqrt(i);

}

intquery(inta,intb)

{

intans=0;

for(inti=a;i<=min(bl[a]*blo,b);i++)

ans+=v[i];

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

ans+=v[i];

for(inti=bl[a]+1;i<=bl[b]-1;i++)

ans+=sum[i];

returnans;

}

intmain()

{

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)

{

bl[i]=(i-1)/blo+1;

sum[bl[i]]+=v[i];

}

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==0)add(a,b,c);

if(f==1)

printf("%d\n",query(a,b));

}

return0;

}

分块入门6:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo,m;

int v[100005];

vectorve[1005];

int st[200005],top;

pair query(int b)

{

int x=1;

while(b>ve[x].size())

b-=ve[x].size(),x++;

return make_pair(x,b-1);

}

void rebuild()

{

top=0;

for(int i=1;i<=m;i++)

{

for(vector::iterator j=ve[i].begin();j!=ve[i].end();j++)

st[++top]=*j;

ve[i].clear();

}

int blo2=sqrt(top);

for(int i=1;i<=top;i++)

ve[(i-1)/blo2+1].push_back(st[i]);

m=(top-1)/blo2+1;

}

void insert(int a,int b)

{

pair t=query(a);

ve[t.first].insert(ve[t.first].begin()+t.second,b);

if(ve[t.first].size()>20*blo)

rebuild();

}

int main()

{

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)

ve[(i-1)/blo+1].push_back(v[i]);

m=(n-1)/blo+1;

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==0)insert(a,b);

if(f==1)

{

pair t=query(b);

printf("%d\n",ve[t.first][t.second]);

}

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo,m;

intv[100005];

vectorve[1005];

intst[200005],top;

pairquery(intb)

{

intx=1;

while(b>ve[x].size())

b-=ve[x].size(),x++;

returnmake_pair(x,b-1);

}

voidrebuild()

{

top=0;

for(inti=1;i<=m;i++)

{

for(vector::iteratorj=ve[i].begin();j!=ve[i].end();j++)

st[++top]=*j;

ve[i].clear();

}

intblo2=sqrt(top);

for(inti=1;i<=top;i++)

ve[(i-1)/blo2+1].push_back(st[i]);

m=(top-1)/blo2+1;

}

voidinsert(inta,intb)

{

pairt=query(a);

ve[t.first].insert(ve[t.first].begin()+t.second,b);

if(ve[t.first].size()>20*blo)

rebuild();

}

intmain()

{

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)

ve[(i-1)/blo+1].push_back(v[i]);

m=(n-1)/blo+1;

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==0)insert(a,b);

if(f==1)

{

pairt=query(b);

printf("%d\n",ve[t.first][t.second]);

}

}

return0;

}

分块入门7:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 10007

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int v[100005],bl[100005],atag[1005],mtag[1005];

void reset(int x)

{

for(int i=(x-1)*blo+1;i<=min(n,x*blo);i++)

v[i]=(v[i]*mtag[x]+atag[x])%mod;

atag[x]=0;mtag[x]=1;

}

void solve(int f,int a,int b,int c)

{

reset(bl[a]);

for(int i=a;i<=min(bl[a]*blo,b);i++)

{

if(f==0)v[i]+=c;

else v[i]*=c;

v[i]%=mod;

}

if(bl[a]!=bl[b])

{

reset(bl[b]);

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

{

if(f==0)v[i]+=c;

else v[i]*=c;

v[i]%=mod;

}

}

for(int i=bl[a]+1;i<=bl[b]-1;i++)

{

if(f==0)atag[i]=(atag[i]+c)%mod;

else

{

atag[i]=(atag[i]*c)%mod;

mtag[i]=(mtag[i]*c)%mod;

}

}

}

int main()

{

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(int i=1;i<=bl[n];i++)mtag[i]=1;

for(int i=1;i<=n;i++)

{

int f=read(),a=read(),b=read(),c=read();

if(f==2)printf("%d\n",(v[b]*mtag[bl[b]]+atag[bl[b]])%mod);

else solve(f,a,b,c);

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 10007

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intv[100005],bl[100005],atag[1005],mtag[1005];

voidreset(intx)

{

for(inti=(x-1)*blo+1;i<=min(n,x*blo);i++)

v[i]=(v[i]*mtag[x]+atag[x])%mod;

atag[x]=0;mtag[x]=1;

}

voidsolve(intf,inta,intb,intc)

{

reset(bl[a]);

for(inti=a;i<=min(bl[a]*blo,b);i++)

{

if(f==0)v[i]+=c;

elsev[i]*=c;

v[i]%=mod;

}

if(bl[a]!=bl[b])

{

reset(bl[b]);

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

{

if(f==0)v[i]+=c;

elsev[i]*=c;

v[i]%=mod;

}

}

for(inti=bl[a]+1;i<=bl[b]-1;i++)

{

if(f==0)atag[i]=(atag[i]+c)%mod;

else

{

atag[i]=(atag[i]*c)%mod;

mtag[i]=(mtag[i]*c)%mod;

}

}

}

intmain()

{

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(inti=1;i<=bl[n];i++)mtag[i]=1;

for(inti=1;i<=n;i++)

{

intf=read(),a=read(),b=read(),c=read();

if(f==2)printf("%d\n",(v[b]*mtag[bl[b]]+atag[bl[b]])%mod);

elsesolve(f,a,b,c);

}

return0;

}

分块入门8:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo;

int v[100005],bl[100005],tag[100005];

void reset(int x)

{

if(tag[x]==-1)return;

for(int i=(x-1)*blo+1;i<=blo*x;i++)

v[i]=tag[x];

tag[x]=-1;

}

int solve(int a,int b,int c)

{

int ans=0;

reset(bl[a]);

for(int i=a;i<=min(bl[a]*blo,b);i++)

if(v[i]!=c)v[i]=c;

else ans++;

if(bl[a]!=bl[b])

{

reset(bl[b]);

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

if(v[i]!=c)v[i]=c;

else ans++;

}

for(int i=bl[a]+1;i<=bl[b]-1;i++)

if(tag[i]!=-1)

{

if(tag[i]!=c)tag[i]=c;

else ans+=blo;

}

else

{

for(int j=(i-1)*blo+1;j<=i*blo;j++)

if(v[j]!=c)v[j]=c;

else ans++;

tag[i]=c;

}

return ans;

}

int main()

{

memset(tag,-1,sizeof(tag));

n=read();blo=sqrt(n);

for(int i=1;i<=n;i++)v[i]=read();

for(int i=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(int i=1;i<=n;i++)

{

int a=read(),b=read(),c=read();

printf("%d\n",solve(a,b,c));

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 998244353

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo;

intv[100005],bl[100005],tag[100005];

voidreset(intx)

{

if(tag[x]==-1)return;

for(inti=(x-1)*blo+1;i<=blo*x;i++)

v[i]=tag[x];

tag[x]=-1;

}

intsolve(inta,intb,intc)

{

intans=0;

reset(bl[a]);

for(inti=a;i<=min(bl[a]*blo,b);i++)

if(v[i]!=c)v[i]=c;

elseans++;

if(bl[a]!=bl[b])

{

reset(bl[b]);

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

if(v[i]!=c)v[i]=c;

elseans++;

}

for(inti=bl[a]+1;i<=bl[b]-1;i++)

if(tag[i]!=-1)

{

if(tag[i]!=c)tag[i]=c;

elseans+=blo;

}

else

{

for(intj=(i-1)*blo+1;j<=i*blo;j++)

if(v[j]!=c)v[j]=c;

elseans++;

tag[i]=c;

}

returnans;

}

intmain()

{

memset(tag,-1,sizeof(tag));

n=read();blo=sqrt(n);

for(inti=1;i<=n;i++)v[i]=read();

for(inti=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(inti=1;i<=n;i++)

{

inta=read(),b=read(),c=read();

printf("%d\n",solve(a,b,c));

}

return0;

}

分块入门9:

C++

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 10007

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

using namespace std;

ll read()

{

ll x=0,f=1;char ch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

return x*f;

}

int n,blo,id;

int v[50005],bl[50005];

int f[505][505];

mapmp;

int val[50005],cnt[50005];

vectorve[50005];

void pre(int x)

{

memset(cnt,0,sizeof(cnt));

int mx=0,ans=0;

for(int i=(x-1)*blo+1;i<=n;i++)

{

cnt[v[i]]++;

int t=bl[i];

if(cnt[v[i]]>mx||(cnt[v[i]]==mx&&val[v[i]]

ans=v[i],mx=cnt[v[i]];

f[x][t]=ans;

}

}

int query(int l,int r,int x)

{

int t=upper_bound(ve[x].begin(),ve[x].end(),r)-lower_bound(ve[x].begin(),ve[x].end(),l);

return t;

}

int query(int a,int b)

{

int ans,mx;

ans=f[bl[a]+1][bl[b]-1];

mx=query(a,b,ans);

for(int i=a;i<=min(bl[a]*blo,b);i++)

{

int t=query(a,b,v[i]);

if(t>mx||(t==mx&&val[v[i]]

}

if(bl[a]!=bl[b])

for(int i=(bl[b]-1)*blo+1;i<=b;i++)

{

int t=query(a,b,v[i]);

if(t>mx||(t==mx&&val[v[i]]

}

return ans;

}

int main()

{

n=read();

blo=200;

for(int i=1;i<=n;i++)

{

v[i]=read();

if(!mp[v[i]])

{

mp[v[i]]=++id;

val[id]=v[i];

}

v[i]=mp[v[i]];

ve[v[i]].push_back(i);

}

for(int i=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(int i=1;i<=bl[n];i++)pre(i);

for(int i=1;i<=n;i++)

{

int a=read(),b=read();

if(a>b)swap(a,b);

printf("%d\n",val[query(a,b)]);

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mod 10007

#define pi acos(-1)

#define inf 0x7fffffff

#define ll long long

usingnamespacestd;

llread()

{

llx=0,f=1;charch=getchar();

while(ch'9'){if(ch=='-')f=-1;ch=getchar();}

while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

returnx*f;

}

intn,blo,id;

intv[50005],bl[50005];

intf[505][505];

mapmp;

intval[50005],cnt[50005];

vectorve[50005];

voidpre(intx)

{

memset(cnt,0,sizeof(cnt));

intmx=0,ans=0;

for(inti=(x-1)*blo+1;i<=n;i++)

{

cnt[v[i]]++;

intt=bl[i];

if(cnt[v[i]]>mx||(cnt[v[i]]==mx&&val[v[i]]

ans=v[i],mx=cnt[v[i]];

f[x][t]=ans;

}

}

intquery(intl,intr,intx)

{

intt=upper_bound(ve[x].begin(),ve[x].end(),r)-lower_bound(ve[x].begin(),ve[x].end(),l);

returnt;

}

intquery(inta,intb)

{

intans,mx;

ans=f[bl[a]+1][bl[b]-1];

mx=query(a,b,ans);

for(inti=a;i<=min(bl[a]*blo,b);i++)

{

intt=query(a,b,v[i]);

if(t>mx||(t==mx&&val[v[i]]

}

if(bl[a]!=bl[b])

for(inti=(bl[b]-1)*blo+1;i<=b;i++)

{

intt=query(a,b,v[i]);

if(t>mx||(t==mx&&val[v[i]]

}

returnans;

}

intmain()

{

n=read();

blo=200;

for(inti=1;i<=n;i++)

{

v[i]=read();

if(!mp[v[i]])

{

mp[v[i]]=++id;

val[id]=v[i];

}

v[i]=mp[v[i]];

ve[v[i]].push_back(i);

}

for(inti=1;i<=n;i++)bl[i]=(i-1)/blo+1;

for(inti=1;i<=bl[n];i++)pre(i);

for(inti=1;i<=n;i++)

{

inta=read(),b=read();

if(a>b)swap(a,b);

printf("%d\n",val[query(a,b)]);

}

return0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值