• 数列分块入门 1 总结


    Question:

    在这里插入图片描述
    这题分块在这里插入图片描述
    这里的删除线有点毒瘤啊。。。
    我们设一个block[]表示第i位属于哪个块。
    我们便可以这样子打:

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

    然后,对于opt==0
    我们发现它除了整个块,但两边可能会有一点点的多出来(就是不够一整个块)
    这两边我们可以暴力搞,而中间的,我们便存一个b[]表示第i块整体加了多少。

    	for (int i=l;i<=min(bl[l]*st,r);i++) a[i]+=c;
    	if (bl[l]!=bl[r])
    		for (int i=(bl[r]-1)*st+1;i<=r;i++) a[i]+=c;
    	for (int j=bl[l]+1;j<=bl[r]-1;j++) b[j]+=c;
    

    对于opt==1
    呵呵,简单,直接输出a[r]+b[block[r]] 即可。

    完整代码如下:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,a[50010],b[231],opt,l,r,c,st;
    int bl[50010];
    
    inline int read()
    {
    	int x=0,f=0; char c=getchar();
    	while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return f ? -x:x;
    }
    
    void add(int l,int r,int c)
    {
    	for (int i=l;i<=min(bl[l]*st,r);i++) a[i]+=c;
    	if (bl[l]!=bl[r])
    		for (int i=(bl[r]-1)*st+1;i<=r;i++) a[i]+=c;
    	for (int j=bl[l]+1;j<=bl[r]-1;j++) b[j]+=c;
    }
    
    int main()
    {
    	freopen("6277.in","r",stdin);
    	freopen("6277.out","w",stdout);
    	n=read();st=sqrt(n);
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++) bl[i]=(i-1)/st+1;
    	for (int i=1;i<=n;i++)
    	{
    		opt=read(),l=read(),r=read(),c=read();
    		if (opt==0) add(l,r,c);
    		else printf("%d
    ",a[r]+b[bl[r]]);
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    9-day9-生成器-列表解析-三元表达式-
    8-day8-列表解析-装饰器-迭代器
    7-day7-闭包函数-装饰器-函数2
    6-day6-函数-1
    5-day5-字符编码-函数-文件操作
    hive 跨年周如何处理
    nginx 安装部署
    logstash 读取kafka output ES
    leedcode 001 之 Two Sum 42.20% Easy
    大数据调度与数据质量的重要性
  • 原文地址:https://www.cnblogs.com/jz929/p/11817656.html
Copyright © 2020-2023  润新知