• 数列分块入门 4 总结


    在这里插入图片描述
    这题变得容易了。。。
    只要记录一下每个块的总和即可。
    左右两边凸出来的暴力搞就可以了。
    上标:
    感觉别人有毒吧,我跑1000ms+,他/她™只跑100ms+。。。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    using namespace std;
    int a[50010],d[321],n,b[321];
    int opt,l,r,c,st;
    int bl[50010],le[321],ri[321];
    
    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(ri[bl[l]],r);i++)
    		a[i]+=c,d[bl[l]]+=c;
    	if (bl[l]!=bl[r])
    	{
    		for (int i=le[bl[r]];i<=r;i++)
    			a[i]+=c,d[bl[r]]+=c;
    	}
    	for (int i=bl[l]+1;i<=bl[r]-1;i++) b[i]+=c;
    }
    
    int query(int l,int r,int c)
    {
    	ll ans=0;
    	for (int i=l;i<=min(ri[bl[l]],r);i++)
    		ans=(ans+a[i]+b[bl[l]])%c;
    	if (bl[l]!=bl[r])
    	{
    		for (int i=le[bl[r]];i<=r;i++)
    			ans=(ans+a[i]+b[bl[r]])%c;
    	}
    	for (int i=bl[l]+1;i<=bl[r]-1;i++)
    		ans=(ans+d[i]+(ll)b[i]*(ri[i]-le[i]+1))%c;
    	return ans;
    }
    
    int main()
    {
    	freopen("6280.in","r",stdin);
    	freopen("6280.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;
    		d[bl[i]]+=a[i];
    		if (!le[bl[i]]) le[bl[i]]=i;
    		ri[bl[i]]=i;
    	}
    	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
    ",query(l,r,c+1));
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    我的PC必装软件
    NumPy数值计算(1)
    英文标题首字母大写规则
    学渣笔记之矩阵的导数与迹
    测试
    (英文排版测试)Lorem Ipsum
    XeLaTeX插入GB/T 7714-2005规范的参考文献方法
    linux-centos7 下 php 扩展的 编译与安装,以 mysqli 为例
    linux-centos7-vmware 实现与虚拟机共享文件夹宿主机磁盘文件
    linux-centos7 下安装 php-nginx 服务器
  • 原文地址:https://www.cnblogs.com/jz929/p/11817645.html
Copyright © 2020-2023  润新知