• 数列分块入门 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;
    }
    
    转载需注明出处。
  • 相关阅读:
    【MySQL】:利用DCL管理用户和控制权限
    【MySQL】:事务四大特性与隔离级别
    JDBC概述及编程步骤详解
    【MySQL】:多表查询
    【MySQL】:MySQL中四大约束
    MySQL解决DOS窗口乱码问题
    【MySQL】:分组查询where和having
    【MySQL】:利用DQL查询表中的数据
    【MySQL】:利用DML操作表中数据
    【MySQL】:利用DDL操作数据库、表
  • 原文地址:https://www.cnblogs.com/jz929/p/11817656.html
Copyright © 2020-2023  润新知